mirrored from https://www.bouncycastle.org/repositories/bc-java
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathOpenPGPDefaultPolicy.java
More file actions
320 lines (275 loc) · 12.5 KB
/
OpenPGPDefaultPolicy.java
File metadata and controls
320 lines (275 loc) · 12.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
package org.bouncycastle.openpgp.api;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.openpgp.api.util.UTCUtil;
public class OpenPGPDefaultPolicy
implements OpenPGPPolicy
{
private final Map<Integer, Date> documentHashAlgorithmCutoffDates = new HashMap<Integer, Date>();
private final Map<Integer, Date> certificateHashAlgorithmCutoffDates = new HashMap<Integer, Date>();
private final Map<Integer, Date> symmetricKeyAlgorithmCutoffDates = new HashMap<Integer, Date>();
private final Map<Integer, Integer> publicKeyMinimalBitStrengths = new HashMap<Integer, Integer>();
private int defaultDocumentSignatureHashAlgorithm = HashAlgorithmTags.SHA512;
private int defaultCertificationSignatureHashAlgorithm = HashAlgorithmTags.SHA512;
private int defaultSymmetricKeyAlgorithm = SymmetricKeyAlgorithmTags.AES_128;
private OpenPGPCertificate.ComponentSignatureEvaluator componentSignatureEvaluator;
public OpenPGPDefaultPolicy()
{
/*
* Certification Signature Hash Algorithms
*/
setDefaultCertificationSignatureHashAlgorithm(HashAlgorithmTags.SHA512);
// SHA-3
acceptCertificationSignatureHashAlgorithm(HashAlgorithmTags.SHA3_512);
acceptCertificationSignatureHashAlgorithm(HashAlgorithmTags.SHA3_256);
// SHA-2
acceptCertificationSignatureHashAlgorithm(HashAlgorithmTags.SHA512);
acceptCertificationSignatureHashAlgorithm(HashAlgorithmTags.SHA384);
acceptCertificationSignatureHashAlgorithm(HashAlgorithmTags.SHA256);
acceptCertificationSignatureHashAlgorithm(HashAlgorithmTags.SHA224);
// SHA-1
acceptCertificationSignatureHashAlgorithmUntil(HashAlgorithmTags.SHA1, UTCUtil.parse("2023-02-01 00:00:00 UTC"));
acceptCertificationSignatureHashAlgorithmUntil(HashAlgorithmTags.RIPEMD160, UTCUtil.parse("2023-02-01 00:00:00 UTC"));
acceptCertificationSignatureHashAlgorithmUntil(HashAlgorithmTags.MD5, UTCUtil.parse("1997-02-01 00:00:00 UTC"));
/*
* Document Signature Hash Algorithms
*/
setDefaultDocumentSignatureHashAlgorithm(HashAlgorithmTags.SHA512);
// SHA-3
acceptDocumentSignatureHashAlgorithm(HashAlgorithmTags.SHA3_512);
acceptDocumentSignatureHashAlgorithm(HashAlgorithmTags.SHA3_256);
// SHA-2
acceptDocumentSignatureHashAlgorithm(HashAlgorithmTags.SHA512);
acceptDocumentSignatureHashAlgorithm(HashAlgorithmTags.SHA384);
acceptDocumentSignatureHashAlgorithm(HashAlgorithmTags.SHA256);
acceptDocumentSignatureHashAlgorithm(HashAlgorithmTags.SHA224);
/*
* Symmetric Key Algorithms
*/
setDefaultSymmetricKeyAlgorithm(SymmetricKeyAlgorithmTags.AES_128);
acceptSymmetricKeyAlgorithm(SymmetricKeyAlgorithmTags.AES_256);
acceptSymmetricKeyAlgorithm(SymmetricKeyAlgorithmTags.AES_192);
acceptSymmetricKeyAlgorithm(SymmetricKeyAlgorithmTags.AES_128);
acceptSymmetricKeyAlgorithm(SymmetricKeyAlgorithmTags.TWOFISH);
acceptSymmetricKeyAlgorithm(SymmetricKeyAlgorithmTags.CAMELLIA_256);
acceptSymmetricKeyAlgorithm(SymmetricKeyAlgorithmTags.CAMELLIA_192);
acceptSymmetricKeyAlgorithm(SymmetricKeyAlgorithmTags.CAMELLIA_128);
/*
* Public Key Algorithms and key strengths
*/
acceptPublicKeyAlgorithmWithMinimalStrength(PublicKeyAlgorithmTags.RSA_GENERAL, 2000);
acceptPublicKeyAlgorithmWithMinimalStrength(PublicKeyAlgorithmTags.RSA_ENCRYPT, 2000);
acceptPublicKeyAlgorithmWithMinimalStrength(PublicKeyAlgorithmTags.RSA_SIGN, 2000);
acceptPublicKeyAlgorithmWithMinimalStrength(PublicKeyAlgorithmTags.ECDSA, 250);
acceptPublicKeyAlgorithmWithMinimalStrength(PublicKeyAlgorithmTags.EDDSA_LEGACY, 250);
acceptPublicKeyAlgorithmWithMinimalStrength(PublicKeyAlgorithmTags.ECDH, 250);
acceptPublicKeyAlgorithm(PublicKeyAlgorithmTags.X25519);
acceptPublicKeyAlgorithm(PublicKeyAlgorithmTags.X448);
acceptPublicKeyAlgorithm(PublicKeyAlgorithmTags.Ed25519);
acceptPublicKeyAlgorithm(PublicKeyAlgorithmTags.Ed448);
/*
* Certificate component signature evaluation
*/
// Strictly constrain the temporal validity of component signatures during signature evaluation.
// This is consistent with legacy OpenPGP implementations.
applyStrictTemporalComponentSignatureValidityConstraints();
}
public OpenPGPDefaultPolicy rejectHashAlgorithm(int hashAlgorithmId)
{
certificateHashAlgorithmCutoffDates.remove(hashAlgorithmId);
documentHashAlgorithmCutoffDates.remove(hashAlgorithmId);
return this;
}
public OpenPGPDefaultPolicy acceptCertificationSignatureHashAlgorithm(int hashAlgorithmId)
{
return acceptCertificationSignatureHashAlgorithmUntil(hashAlgorithmId, null);
}
public OpenPGPDefaultPolicy acceptCertificationSignatureHashAlgorithmUntil(int hashAlgorithmId, Date until)
{
certificateHashAlgorithmCutoffDates.put(hashAlgorithmId, until);
return this;
}
public OpenPGPDefaultPolicy acceptDocumentSignatureHashAlgorithm(int hashAlgorithmId)
{
return acceptDocumentSignatureHashAlgorithmUntil(hashAlgorithmId, null);
}
public OpenPGPDefaultPolicy acceptDocumentSignatureHashAlgorithmUntil(int hashAlgorithmId, Date until)
{
documentHashAlgorithmCutoffDates.put(hashAlgorithmId, until);
return this;
}
public OpenPGPDefaultPolicy rejectSymmetricKeyAlgorithm(int symmetricKeyAlgorithmId)
{
symmetricKeyAlgorithmCutoffDates.remove(symmetricKeyAlgorithmId);
return this;
}
public OpenPGPDefaultPolicy acceptSymmetricKeyAlgorithm(int symmetricKeyAlgorithmId)
{
return acceptSymmetricKeyAlgorithmUntil(symmetricKeyAlgorithmId, null);
}
public OpenPGPDefaultPolicy acceptSymmetricKeyAlgorithmUntil(int symmetricKeyAlgorithmId, Date until)
{
symmetricKeyAlgorithmCutoffDates.put(symmetricKeyAlgorithmId, until);
return this;
}
public OpenPGPDefaultPolicy rejectPublicKeyAlgorithm(int publicKeyAlgorithmId)
{
publicKeyMinimalBitStrengths.remove(publicKeyAlgorithmId);
return this;
}
public OpenPGPDefaultPolicy acceptPublicKeyAlgorithm(int publicKeyAlgorithmId)
{
publicKeyMinimalBitStrengths.put(publicKeyAlgorithmId, null);
return this;
}
public OpenPGPDefaultPolicy acceptPublicKeyAlgorithmWithMinimalStrength(int publicKeyAlgorithmId, int minBitStrength)
{
publicKeyMinimalBitStrengths.put(publicKeyAlgorithmId, minBitStrength);
return this;
}
@Override
public boolean isAcceptableDocumentSignatureHashAlgorithm(int hashAlgorithmId, Date signatureCreationTime)
{
return isAcceptable(hashAlgorithmId, signatureCreationTime, documentHashAlgorithmCutoffDates);
}
@Override
public boolean isAcceptableRevocationSignatureHashAlgorithm(int hashAlgorithmId, Date signatureCreationTime)
{
return isAcceptable(hashAlgorithmId, signatureCreationTime, certificateHashAlgorithmCutoffDates);
}
@Override
public boolean isAcceptableCertificationSignatureHashAlgorithm(int hashAlgorithmId, Date signatureCreationTime)
{
return isAcceptable(hashAlgorithmId, signatureCreationTime, certificateHashAlgorithmCutoffDates);
}
@Override
public int getDefaultCertificationSignatureHashAlgorithm()
{
return defaultCertificationSignatureHashAlgorithm;
}
public OpenPGPDefaultPolicy setDefaultCertificationSignatureHashAlgorithm(int hashAlgorithmId)
{
defaultCertificationSignatureHashAlgorithm = hashAlgorithmId;
return this;
}
@Override
public int getDefaultDocumentSignatureHashAlgorithm()
{
return defaultDocumentSignatureHashAlgorithm;
}
public OpenPGPDefaultPolicy setDefaultDocumentSignatureHashAlgorithm(int hashAlgorithmId)
{
defaultDocumentSignatureHashAlgorithm = hashAlgorithmId;
return this;
}
@Override
public boolean isAcceptableSymmetricKeyAlgorithm(int symmetricKeyAlgorithmId)
{
return isAcceptable(symmetricKeyAlgorithmId, symmetricKeyAlgorithmCutoffDates);
}
@Override
public int getDefaultSymmetricKeyAlgorithm()
{
return defaultSymmetricKeyAlgorithm;
}
public OpenPGPDefaultPolicy setDefaultSymmetricKeyAlgorithm(int symmetricKeyAlgorithmId)
{
defaultSymmetricKeyAlgorithm = symmetricKeyAlgorithmId;
return this;
}
@Override
public boolean isAcceptablePublicKeyStrength(int publicKeyAlgorithmId, int bitStrength)
{
return isAcceptable(publicKeyAlgorithmId, bitStrength, publicKeyMinimalBitStrengths);
}
@Override
public OpenPGPCertificate.ComponentSignatureEvaluator getComponentSignatureEffectivenessEvaluator() {
return componentSignatureEvaluator;
}
public OpenPGPDefaultPolicy setComponentSignatureEffectivenessEvaluator(
OpenPGPCertificate.ComponentSignatureEvaluator componentSignatureEvaluator)
{
this.componentSignatureEvaluator = componentSignatureEvaluator;
return this;
}
/**
* When evaluating a document signature or third-party certification issued at time t1,
* only consider component binding signatures made at t1 or prior and reject component
* binding signatures made at t2+.
* This behavior is consistent with OpenPGP implementations, but might break historical
* document signatures and third-party certifications if old component signatures are
* cleaned from the certificate (temporal holes).
* You can prevent temporal holes with {@link #allowRetroactiveComponentSignatureValidation()}.
* <p>
* This behavior is currently the default.
*
* @return policy
*/
public OpenPGPDefaultPolicy applyStrictTemporalComponentSignatureValidityConstraints()
{
return setComponentSignatureEffectivenessEvaluator(
OpenPGPCertificate.strictlyTemporallyConstrainedSignatureEvaluator());
}
/**
* When evaluating a document signature or third-party certification issued at time t1,
* also consider component binding signatures created at t2+.
* This behavior prevents historical document or certification signatures from breaking
* if older binding signatures are cleaned from the issuer certificate.
* Since PQC signatures may quickly blow up the certificate in size, it is desirable to
* clean up old signatures every once in a while and allowing retroactive validation of
* historic signatures via new component signatures prevents temporal holes.
* <p>
* Calling this will overwrite the - currently default - behavior from
* {@link #applyStrictTemporalComponentSignatureValidityConstraints()}.
*
* @return policy
*/
public OpenPGPDefaultPolicy allowRetroactiveComponentSignatureValidation()
{
return setComponentSignatureEffectivenessEvaluator(
OpenPGPCertificate.retroactivelyTemporallyRevalidatingSignatureEvaluator());
}
@Override
public OpenPGPNotationRegistry getNotationRegistry()
{
return null;
}
private boolean isAcceptable(int algorithmId, Date usageDate, Map<Integer, Date> cutoffTable)
{
if (!cutoffTable.containsKey(algorithmId))
{
// algorithm is not listed in the map at all
return false;
}
Date cutoffDate = cutoffTable.get(algorithmId);
if (cutoffDate == null)
{
// no cutoff date given -> algorithm is acceptable indefinitely
return true;
}
return usageDate.before(cutoffDate);
}
private boolean isAcceptable(int algorithmId, Map<Integer, Date> cutoffTable)
{
return cutoffTable.containsKey(algorithmId);
}
private boolean isAcceptable(int algorithmId, int bitStrength, Map<Integer, Integer> minBitStrengths)
{
if (!minBitStrengths.containsKey(algorithmId))
{
// algorithm is not listed in the map at all
return false;
}
Integer minBitStrength = minBitStrengths.get(algorithmId);
if (minBitStrength == null)
{
// no minimal bit strength defined -> accept all strengths
return true;
}
return bitStrength >= minBitStrength;
}
}