Skip to content

Commit 94fadb5

Browse files
committed
Merge branch '1857-4-api-keypairgenerator' into 'main'
OpenPGPV6KeyGeneratorTest and related classes See merge request root/bc-java!48
2 parents 220bf00 + 871bf4b commit 94fadb5

17 files changed

+2444
-18
lines changed

pg/src/main/java/org/bouncycastle/openpgp/PGPSecretKeyRing.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,14 +492,31 @@ public int size()
492492
return keys.size();
493493
}
494494

495+
/**
496+
* Return the OpenPGP certificate (Transferable Public Key) of this key.
497+
*
498+
* @return certificate
499+
*/
500+
public PGPPublicKeyRing toCertificate()
501+
{
502+
List<PGPPublicKey> pubKeys = new ArrayList<PGPPublicKey>();
503+
Iterator<PGPPublicKey> it = getPublicKeys();
504+
while (it.hasNext())
505+
{
506+
pubKeys.add(it.next());
507+
}
508+
return new PGPPublicKeyRing(pubKeys);
509+
}
510+
495511
public byte[] getEncoded()
496512
throws IOException
497513
{
498514
return getEncoded(PacketFormat.ROUNDTRIP);
499515
}
500516

501517
@Override
502-
public byte[] getEncoded(PacketFormat format) throws IOException
518+
public byte[] getEncoded(PacketFormat format)
519+
throws IOException
503520
{
504521
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
505522
BCPGOutputStream pOut = new BCPGOutputStream(bOut, format);

pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureSubpacketGenerator.java

Lines changed: 119 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.IOException;
44
import java.util.ArrayList;
5+
import java.util.Arrays;
56
import java.util.Date;
67
import java.util.List;
78

@@ -38,7 +39,7 @@
3839
*/
3940
public class PGPSignatureSubpacketGenerator
4041
{
41-
List packets = new ArrayList();
42+
List<SignatureSubpacket> packets = new ArrayList<SignatureSubpacket>();
4243

4344
/**
4445
* Base constructor, creates an empty generator.
@@ -56,10 +57,7 @@ public PGPSignatureSubpacketGenerator(PGPSignatureSubpacketVector sigSubV)
5657
{
5758
if (sigSubV != null)
5859
{
59-
for (int i = 0; i != sigSubV.packets.length; i++)
60-
{
61-
packets.add(sigSubV.packets[i]);
62-
}
60+
packets.addAll(Arrays.asList(sigSubV.packets));
6361
}
6462
}
6563

@@ -78,6 +76,18 @@ public void setRevocable(boolean isCritical, boolean isRevocable)
7876
packets.add(new Revocable(isCritical, isRevocable));
7977
}
8078

79+
/**
80+
* Specify, whether the signature should be marked as exportable.
81+
* If this subpacket is missing, the signature is treated as being exportable.
82+
* The subpacket is marked as critical, as is required (for non-exportable signatures) by the spec.
83+
*
84+
* @param isExportable true if the signature should be exportable, false otherwise.
85+
*/
86+
public void setExportable(boolean isExportable)
87+
{
88+
setExportable(true, isExportable);
89+
}
90+
8191
/**
8292
* Specify, whether or not the signature should be marked as exportable.
8393
* If this subpacket is missing, the signature is treated as being exportable.
@@ -119,6 +129,18 @@ public void setTrust(boolean isCritical, int depth, int trustAmount)
119129
packets.add(new TrustSignature(isCritical, depth, trustAmount));
120130
}
121131

132+
/**
133+
* Set the number of seconds a key is valid for after the time of its creation. A
134+
* value of zero means the key never expires.
135+
* The subpacket will be marked as critical, as is recommended by the spec.
136+
*
137+
* @param seconds seconds from key creation to expiration
138+
*/
139+
public void setKeyExpirationTime(long seconds)
140+
{
141+
setKeyExpirationTime(true, seconds);
142+
}
143+
122144
/**
123145
* Set the number of seconds a key is valid for after the time of its creation. A
124146
* value of zero means the key never expires.
@@ -131,6 +153,19 @@ public void setKeyExpirationTime(boolean isCritical, long seconds)
131153
packets.add(new KeyExpirationTime(isCritical, seconds));
132154
}
133155

156+
/**
157+
* Set the number of seconds a signature is valid for after the time of its creation.
158+
* A value of zero means the signature never expires.
159+
* The subpacket will be marked as critical, as is recommended by the spec.
160+
* .
161+
*
162+
* @param seconds seconds from signature creation to expiration
163+
*/
164+
public void setSignatureExpirationTime(long seconds)
165+
{
166+
setSignatureExpirationTime(true, seconds);
167+
}
168+
134169
/**
135170
* Set the number of seconds a signature is valid for after the time of its creation.
136171
* A value of zero means the signature never expires.
@@ -143,6 +178,20 @@ public void setSignatureExpirationTime(boolean isCritical, long seconds)
143178
packets.add(new SignatureExpirationTime(isCritical, seconds));
144179
}
145180

181+
/**
182+
* Set the creation time for the signature.
183+
* The subpacket will be marked as critical, as is recommended by the spec.
184+
* <p>
185+
* Note: this overrides the generation of a creation time when the signature is
186+
* generated.
187+
*
188+
* @param date date
189+
*/
190+
public void setSignatureCreationTime(Date date)
191+
{
192+
setSignatureCreationTime(true, date);
193+
}
194+
146195
/**
147196
* Set the creation time for the signature.
148197
* <p>
@@ -212,11 +261,10 @@ public void setPreferredAEADAlgorithms(boolean isCritical, int[] algorithms)
212261
/**
213262
* Specify the preferred OpenPGP AEAD ciphersuites of this key.
214263
*
215-
* @see <a href="https://www.rfc-editor.org/rfc/rfc9580.html#name-preferred-aead-ciphersuites">
216-
* RFC9580: Preferred AEAD Ciphersuites</a>
217-
*
218264
* @param isCritical true, if this packet should be treated as critical, false otherwise.
219265
* @param algorithms array of algorithms in descending preference
266+
* @see <a href="https://www.rfc-editor.org/rfc/rfc9580.html#name-preferred-aead-ciphersuites">
267+
* RFC9580: Preferred AEAD Ciphersuites</a>
220268
*/
221269
public void setPreferredAEADCiphersuites(boolean isCritical, PreferredAEADCiphersuites.Combination[] algorithms)
222270
{
@@ -226,10 +274,9 @@ public void setPreferredAEADCiphersuites(boolean isCritical, PreferredAEADCipher
226274
/**
227275
* Specify the preferred OpenPGP AEAD ciphersuites of this key.
228276
*
229-
* @see <a href="https://www.rfc-editor.org/rfc/rfc9580.html#name-preferred-aead-ciphersuites">
230-
* RFC9580: Preferred AEAD Ciphersuites</a>
231-
*
232277
* @param builder builder to build the ciphersuites packet from
278+
* @see <a href="https://www.rfc-editor.org/rfc/rfc9580.html#name-preferred-aead-ciphersuites">
279+
* RFC9580: Preferred AEAD Ciphersuites</a>
233280
*/
234281
public void setPreferredAEADCiphersuites(PreferredAEADCiphersuites.Builder builder)
235282
{
@@ -243,12 +290,11 @@ public void setPreferredAEADCiphersuites(PreferredAEADCiphersuites.Builder build
243290
* The LibrePGP spec states that this subpacket shall be ignored and the application shall instead assume
244291
* {@link org.bouncycastle.bcpg.AEADAlgorithmTags#OCB}.
245292
*
246-
* @see <a href="https://www.ietf.org/archive/id/draft-koch-librepgp-01.html#name-preferred-encryption-modes">
247-
* LibrePGP: Preferred Encryption Modes</a>
248-
* @see org.bouncycastle.bcpg.AEADAlgorithmTags for possible algorithms
249-
*
250293
* @param isCritical whether the packet is critical
251294
* @param algorithms list of algorithms
295+
* @see <a href="https://www.ietf.org/archive/id/draft-koch-librepgp-01.html#name-preferred-encryption-modes">
296+
* LibrePGP: Preferred Encryption Modes</a>
297+
* @see org.bouncycastle.bcpg.AEADAlgorithmTags for possible algorithms
252298
* @deprecated the use of this subpacket is deprecated in LibrePGP
253299
*/
254300
@Deprecated
@@ -262,7 +308,7 @@ public void setPreferredLibrePgpEncryptionModes(boolean isCritical, int[] algori
262308
* Note, that the key server might also be a http/ftp etc. URI pointing to the key itself.
263309
*
264310
* @param isCritical true if the subpacket should be treated as critical
265-
* @param uri key server URI
311+
* @param uri key server URI
266312
*/
267313
public void setPreferredKeyServer(boolean isCritical, String uri)
268314
{
@@ -274,6 +320,18 @@ public void addPolicyURI(boolean isCritical, String policyUri)
274320
packets.add(new PolicyURI(isCritical, policyUri));
275321
}
276322

323+
/**
324+
* Set this keys key flags.
325+
* See {@link PGPKeyFlags}.
326+
* The subpacket will be marked as critical, as is recommended by the spec.
327+
*
328+
* @param flags flags
329+
*/
330+
public void setKeyFlags(int flags)
331+
{
332+
setKeyFlags(true, flags);
333+
}
334+
277335
/**
278336
* Set this keys key flags.
279337
* See {@link PGPKeyFlags}.
@@ -515,6 +573,19 @@ public void setIntendedRecipientFingerprint(boolean isCritical, PGPPublicKey pub
515573
addIntendedRecipientFingerprint(isCritical, publicKey);
516574
}
517575

576+
/**
577+
* Adds a intended recipient fingerprint for an encrypted payload the signature is associated with.
578+
* The subpacket will be marked as critical, as is recommended by the spec.
579+
*
580+
* @param publicKey the public key the encrypted payload was encrypted against.
581+
*/
582+
public void addIntendedRecipientFingerprint(PGPPublicKey publicKey)
583+
{
584+
// RFC9580 states, that the packet SHOULD be critical if generated in a v6 signature,
585+
// but it doesn't harm to default to critical for any signature version
586+
addIntendedRecipientFingerprint(true, publicKey);
587+
}
588+
518589
/**
519590
* Adds a intended recipient fingerprint for an encrypted payload the signature is associated with.
520591
*
@@ -549,6 +620,26 @@ public boolean removePacket(SignatureSubpacket packet)
549620
return packets.remove(packet);
550621
}
551622

623+
/**
624+
* Remove all {@link SignatureSubpacket} objects of the given subpacketType from the underlying subpacket vector.
625+
*
626+
* @param subpacketType type to remove
627+
* @return true if any packet was removed, false otherwise
628+
*/
629+
public boolean removePacketsOfType(int subpacketType)
630+
{
631+
boolean remove = false;
632+
for (int i = packets.size() - 1; i >= 0; i--)
633+
{
634+
if (packets.get(i).getType() == subpacketType)
635+
{
636+
packets.remove(i);
637+
remove = true;
638+
}
639+
}
640+
return remove;
641+
}
642+
552643
/**
553644
* Return true if a particular subpacket type exists.
554645
*
@@ -595,7 +686,7 @@ public SignatureSubpacket[] getSubpackets(
595686
public PGPSignatureSubpacketVector generate()
596687
{
597688
return new PGPSignatureSubpacketVector(
598-
(SignatureSubpacket[])packets.toArray(new SignatureSubpacket[packets.size()]));
689+
packets.toArray(new SignatureSubpacket[0]));
599690
}
600691

601692
private boolean contains(int type)
@@ -610,6 +701,17 @@ private boolean contains(int type)
610701
return false;
611702
}
612703

704+
/**
705+
* Adds a regular expression.
706+
* The subpacket is marked as critical, as is recommended by the spec.
707+
*
708+
* @param regularExpression the regular expression
709+
*/
710+
public void addRegularExpression(String regularExpression)
711+
{
712+
addRegularExpression(true, regularExpression);
713+
}
714+
613715
/**
614716
* Adds a regular expression.
615717
*
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.bouncycastle.openpgp.api;
2+
3+
import org.bouncycastle.openpgp.PGPException;
4+
import org.bouncycastle.openpgp.PGPKeyPair;
5+
import org.bouncycastle.openpgp.operator.PGPKeyPairGenerator;
6+
7+
/**
8+
* Callback to generate a {@link PGPKeyPair} from a {@link PGPKeyPairGenerator} instance.
9+
*/
10+
@FunctionalInterface
11+
public interface KeyPairGeneratorCallback
12+
{
13+
/**
14+
* Generate a {@link PGPKeyPair} by calling a factory method on a given generator instance.
15+
*
16+
* @param generator PGPKeyPairGenerator
17+
* @return generated key pair
18+
* @throws PGPException
19+
*/
20+
PGPKeyPair generateFrom(PGPKeyPairGenerator generator)
21+
throws PGPException;
22+
}

0 commit comments

Comments
 (0)