Skip to content

Commit b506184

Browse files
committed
Merge branch 'main' of gitlab.cryptoworkshop.com:root/bc-java
2 parents 9c9a60c + 7526030 commit b506184

14 files changed

Lines changed: 294 additions & 177 deletions

File tree

core/src/main/java/org/bouncycastle/asn1/BEROctetString.java

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import java.io.IOException;
44

5+
import org.bouncycastle.util.Arrays;
6+
57
/**
68
* ASN.1 OctetStrings, with indefinite length rules, and <i>constructed form</i> support.
79
* <p>
@@ -19,10 +21,37 @@
1921
public class BEROctetString
2022
extends ASN1OctetString
2123
{
22-
private static final int DEFAULT_SEGMENT_LIMIT = 1000;
24+
public static final BEROctetString EMPTY = new BEROctetString(EMPTY_OCTETS);
2325

24-
private final int segmentLimit;
25-
private final ASN1OctetString[] elements;
26+
public static BEROctetString fromContents(byte[] contents)
27+
{
28+
if (contents == null)
29+
{
30+
throw new NullPointerException("'contents' cannot be null");
31+
}
32+
33+
return internalFromContents(contents);
34+
}
35+
36+
public static BEROctetString fromContentsOptional(byte[] contents)
37+
{
38+
return contents == null ? null : internalFromContents(contents);
39+
}
40+
41+
public static BEROctetString withContents(byte[] contents)
42+
{
43+
if (contents == null)
44+
{
45+
throw new NullPointerException("'contents' cannot be null");
46+
}
47+
48+
return internalWithContents(contents);
49+
}
50+
51+
public static BEROctetString withContentsOptional(byte[] contents)
52+
{
53+
return contents == null ? null : internalWithContents(contents);
54+
}
2655

2756
/**
2857
* Convert a vector of octet strings into a single byte string
@@ -58,6 +87,21 @@ static byte[] flattenOctetStrings(ASN1OctetString[] octetStrings)
5887
}
5988
}
6089

90+
static BEROctetString internalFromContents(byte[] contents)
91+
{
92+
return contents.length < 1 ? EMPTY : new BEROctetString(Arrays.clone(contents));
93+
}
94+
95+
static BEROctetString internalWithContents(byte[] contents)
96+
{
97+
return contents.length < 1 ? EMPTY : new BEROctetString(contents);
98+
}
99+
100+
private static final int DEFAULT_SEGMENT_LIMIT = 1000;
101+
102+
private final int segmentLimit;
103+
private final ASN1OctetString[] elements;
104+
61105
/**
62106
* Create an OCTET-STRING object from a byte[]
63107
* @param string the octets making up the octet string.

core/src/main/java/org/bouncycastle/asn1/DEROctetString.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,56 @@
22

33
import java.io.IOException;
44

5+
import org.bouncycastle.util.Arrays;
6+
57
/**
68
* Carrier class for a DER encoding OCTET STRING
79
*/
810
public class DEROctetString
911
extends ASN1OctetString
1012
{
13+
public static final DEROctetString EMPTY = new DEROctetString(EMPTY_OCTETS);
14+
15+
public static DEROctetString fromContents(byte[] contents)
16+
{
17+
if (contents == null)
18+
{
19+
throw new NullPointerException("'contents' cannot be null");
20+
}
21+
22+
return internalFromContents(contents);
23+
}
24+
25+
public static DEROctetString fromContentsOptional(byte[] contents)
26+
{
27+
return contents == null ? null : internalFromContents(contents);
28+
}
29+
30+
public static DEROctetString withContents(byte[] contents)
31+
{
32+
if (contents == null)
33+
{
34+
throw new NullPointerException("'contents' cannot be null");
35+
}
36+
37+
return internalWithContents(contents);
38+
}
39+
40+
public static DEROctetString withContentsOptional(byte[] contents)
41+
{
42+
return contents == null ? null : internalWithContents(contents);
43+
}
44+
45+
static DEROctetString internalFromContents(byte[] contents)
46+
{
47+
return contents.length < 1 ? EMPTY : new DEROctetString(Arrays.clone(contents));
48+
}
49+
50+
static DEROctetString internalWithContents(byte[] contents)
51+
{
52+
return contents.length < 1 ? EMPTY : new DEROctetString(contents);
53+
}
54+
1155
/**
1256
* Base constructor.
1357
*

core/src/main/java/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
*/
1616
public interface SECObjectIdentifiers
1717
{
18-
/** Base OID: 1.3.132.0 */
19-
static final ASN1ObjectIdentifier ellipticCurve = new ASN1ObjectIdentifier("1.3.132.0");
18+
static final ASN1ObjectIdentifier certicom = new ASN1ObjectIdentifier("1.3.132");
19+
20+
static final ASN1ObjectIdentifier ellipticCurve = certicom.branch("0");
2021

2122
/** sect163k1 OID: 1.3.132.0.1 */
2223
static final ASN1ObjectIdentifier sect163k1 = ellipticCurve.branch("1");
@@ -86,25 +87,52 @@ public interface SECObjectIdentifiers
8687
/** secp256r1 OID: 1.3.132.0.prime256v1 */
8788
static final ASN1ObjectIdentifier secp256r1 = X9ObjectIdentifiers.prime256v1;
8889

89-
static final ASN1ObjectIdentifier secg_scheme = new ASN1ObjectIdentifier("1.3.132.1");
90+
static final ASN1ObjectIdentifier secg_scheme = certicom.branch("1");
91+
92+
static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_recommendedKDF = secg_scheme.branch("1");
93+
static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_specifiedKDF = secg_scheme.branch("2");
94+
static final ASN1ObjectIdentifier mqvSinglePass_recommendedKDF = secg_scheme.branch("3");
95+
static final ASN1ObjectIdentifier mqvSinglePass_specifiedKDF = secg_scheme.branch("4");
96+
static final ASN1ObjectIdentifier mqvFull_recommendedKDF = secg_scheme.branch("5");
97+
static final ASN1ObjectIdentifier mqvFull_specifiedKDF = secg_scheme.branch("6");
98+
static final ASN1ObjectIdentifier ecies_recommendedParameters = secg_scheme.branch("7");
99+
static final ASN1ObjectIdentifier ecies_specifiedParameters = secg_scheme.branch("8");
100+
101+
static final ASN1ObjectIdentifier dhSinglePass_stdDH_kdf_schemes = secg_scheme.branch("11");
102+
103+
static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha224kdf_scheme = dhSinglePass_stdDH_kdf_schemes.branch("0");
104+
static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha256kdf_scheme = dhSinglePass_stdDH_kdf_schemes.branch("1");
105+
static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha384kdf_scheme = dhSinglePass_stdDH_kdf_schemes.branch("2");
106+
static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha512kdf_scheme = dhSinglePass_stdDH_kdf_schemes.branch("3");
107+
108+
static final ASN1ObjectIdentifier ecdh = secg_scheme.branch("12");
109+
static final ASN1ObjectIdentifier ecmqv = secg_scheme.branch("13");
110+
111+
static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_kdf_schemes = secg_scheme.branch("14");
112+
113+
static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha224kdf_scheme = dhSinglePass_cofactorDH_kdf_schemes.branch("0");
114+
static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha256kdf_scheme = dhSinglePass_cofactorDH_kdf_schemes.branch("1");
115+
static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha384kdf_scheme = dhSinglePass_cofactorDH_kdf_schemes.branch("2");
116+
static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha512kdf_scheme = dhSinglePass_cofactorDH_kdf_schemes.branch("3");
117+
118+
static final ASN1ObjectIdentifier mqvSinglePass_kdf_schemes = secg_scheme.branch("15");
119+
120+
static final ASN1ObjectIdentifier mqvSinglePass_sha224kdf_scheme = mqvSinglePass_kdf_schemes.branch("0");
121+
static final ASN1ObjectIdentifier mqvSinglePass_sha256kdf_scheme = mqvSinglePass_kdf_schemes.branch("1");
122+
static final ASN1ObjectIdentifier mqvSinglePass_sha384kdf_scheme = mqvSinglePass_kdf_schemes.branch("2");
123+
static final ASN1ObjectIdentifier mqvSinglePass_sha512kdf_scheme = mqvSinglePass_kdf_schemes.branch("3");
90124

91-
static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha224kdf_scheme = secg_scheme.branch("11.0");
92-
static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha256kdf_scheme = secg_scheme.branch("11.1");
93-
static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha384kdf_scheme = secg_scheme.branch("11.2");
94-
static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha512kdf_scheme = secg_scheme.branch("11.3");
125+
static final ASN1ObjectIdentifier mqvFull_kdf_schemes = secg_scheme.branch("16");
95126

96-
static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha224kdf_scheme = secg_scheme.branch("14.0");
97-
static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha256kdf_scheme = secg_scheme.branch("14.1");
98-
static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha384kdf_scheme = secg_scheme.branch("14.2");
99-
static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha512kdf_scheme = secg_scheme.branch("14.3");
127+
static final ASN1ObjectIdentifier mqvFull_sha224kdf_scheme = mqvFull_kdf_schemes.branch("0");
128+
static final ASN1ObjectIdentifier mqvFull_sha256kdf_scheme = mqvFull_kdf_schemes.branch("1");
129+
static final ASN1ObjectIdentifier mqvFull_sha384kdf_scheme = mqvFull_kdf_schemes.branch("2");
130+
static final ASN1ObjectIdentifier mqvFull_sha512kdf_scheme = mqvFull_kdf_schemes.branch("3");
100131

101-
static final ASN1ObjectIdentifier mqvSinglePass_sha224kdf_scheme = secg_scheme.branch("15.0");
102-
static final ASN1ObjectIdentifier mqvSinglePass_sha256kdf_scheme = secg_scheme.branch("15.1");
103-
static final ASN1ObjectIdentifier mqvSinglePass_sha384kdf_scheme = secg_scheme.branch("15.2");
104-
static final ASN1ObjectIdentifier mqvSinglePass_sha512kdf_scheme = secg_scheme.branch("15.3");
132+
static final ASN1ObjectIdentifier kdf_algorithms = secg_scheme.branch("17");
105133

106-
static final ASN1ObjectIdentifier mqvFull_sha224kdf_scheme = secg_scheme.branch("16.0");
107-
static final ASN1ObjectIdentifier mqvFull_sha256kdf_scheme = secg_scheme.branch("16.1");
108-
static final ASN1ObjectIdentifier mqvFull_sha384kdf_scheme = secg_scheme.branch("16.2");
109-
static final ASN1ObjectIdentifier mqvFull_sha512kdf_scheme = secg_scheme.branch("16.3");
134+
static final ASN1ObjectIdentifier x9_63_kdf = kdf_algorithms.branch("0");
135+
static final ASN1ObjectIdentifier nist_concatenation_kdf = kdf_algorithms.branch("1");
136+
static final ASN1ObjectIdentifier tls_kdf = kdf_algorithms.branch("2");
137+
static final ASN1ObjectIdentifier ikev2_kdf = kdf_algorithms.branch("3");
110138
}

core/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ public interface X9ObjectIdentifiers
161161
* <p>
162162
* Base OID: 1.3.133.16.840.63.0
163163
*/
164+
// TODO Seems this ought to be be 1.3.133.16.840.9.63.0, but may be in common use
164165
ASN1ObjectIdentifier x9_63_scheme = new ASN1ObjectIdentifier("1.3.133.16.840.63.0");
165166
/** OID: 1.3.133.16.840.63.0.2 */
166167
ASN1ObjectIdentifier dhSinglePass_stdDH_sha1kdf_scheme = x9_63_scheme.branch("2");

core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,16 @@ else if (algOID.equals(X9ObjectIdentifiers.id_dsa))
152152

153153
return new DSAPrivateKeyParameters(derX.getValue(), parameters);
154154
}
155+
/*
156+
* TODO id-ecDH (SECObjectIdentifiers.ecdh) and/or id-ecMQV (SECObjectIdentifiers.ecmqv) could be supported if
157+
* we could properly restrict usage of the resulting key.
158+
*/
155159
else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey))
156160
{
161+
/*
162+
* TODO Consistency checks in case parameters and/or public key are specified at both the
163+
* PrivateKeyInfo and ECPrivateKey levels?
164+
*/
157165
ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(keyInfo.parsePrivateKey());
158166

159167
X962Parameters parameters = X962Parameters.getInstance(algId.getParameters().toASN1Primitive());

core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ public class PublicKeyFactory
8181
converters.put(X9ObjectIdentifiers.id_dsa, new DSAConverter());
8282
converters.put(OIWObjectIdentifiers.dsaWithSHA1, new DSAConverter());
8383
converters.put(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalConverter());
84+
/*
85+
* TODO id-ecDH (SECObjectIdentifiers.ecdh) and/or id-ecMQV (SECObjectIdentifiers.ecmqv) could be supported if
86+
* we could properly restrict usage of the resulting key.
87+
*/
8488
converters.put(X9ObjectIdentifiers.id_ecPublicKey, new ECConverter());
8589
converters.put(CryptoProObjectIdentifiers.gostR3410_2001, new GOST3410_2001Converter());
8690
converters.put(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, new GOST3410_2012Converter());

pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,16 @@
6161

6262
class CMSUtils
6363
{
64-
private static final Set<String> des = new HashSet<String>();
64+
private static final Set desAlgs = new HashSet();
6565
private static final Set mqvAlgs = new HashSet();
6666
private static final Set ecAlgs = new HashSet();
6767
private static final Set gostAlgs = new HashSet();
6868

6969
static
7070
{
71-
des.add("DES");
72-
des.add("DESEDE");
73-
des.add(OIWObjectIdentifiers.desCBC.getId());
74-
des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId());
75-
des.add(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId());
71+
desAlgs.add(OIWObjectIdentifiers.desCBC);
72+
desAlgs.add(PKCSObjectIdentifiers.des_EDE3_CBC);
73+
desAlgs.add(PKCSObjectIdentifiers.id_alg_CMS3DESwrap);
7674

7775
mqvAlgs.add(X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme);
7876
mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme);
@@ -113,14 +111,13 @@ static boolean isGOST(ASN1ObjectIdentifier algorithm)
113111

114112
static boolean isRFC2631(ASN1ObjectIdentifier algorithm)
115113
{
116-
return algorithm.equals(PKCSObjectIdentifiers.id_alg_ESDH) || algorithm.equals(PKCSObjectIdentifiers.id_alg_SSDH);
114+
return PKCSObjectIdentifiers.id_alg_ESDH.equals(algorithm)
115+
|| PKCSObjectIdentifiers.id_alg_SSDH.equals(algorithm);
117116
}
118117

119-
static boolean isDES(String algorithmID)
118+
static boolean isDES(ASN1ObjectIdentifier algorithm)
120119
{
121-
String name = Strings.toUpperCase(algorithmID);
122-
123-
return des.contains(name);
120+
return desAlgs.contains(algorithm);
124121
}
125122

126123
static boolean isEquivalent(AlgorithmIdentifier algId1, AlgorithmIdentifier algId2)
Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.bouncycastle.cms;
22

3+
import org.bouncycastle.asn1.ASN1Encodable;
34
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
5+
import org.bouncycastle.asn1.ASN1OctetString;
46
import org.bouncycastle.asn1.ASN1Sequence;
57
import org.bouncycastle.asn1.DERNull;
68
import org.bouncycastle.asn1.DEROctetString;
@@ -18,64 +20,50 @@
1820
public abstract class KeyAgreeRecipientInfoGenerator
1921
implements RecipientInfoGenerator
2022
{
21-
private ASN1ObjectIdentifier keyAgreementOID;
22-
private ASN1ObjectIdentifier keyEncryptionOID;
23-
private SubjectPublicKeyInfo originatorKeyInfo;
23+
private final ASN1ObjectIdentifier keyAgreementOID;
24+
private final ASN1ObjectIdentifier keyEncryptionOID;
25+
private final SubjectPublicKeyInfo originatorKeyInfo;
2426

25-
protected KeyAgreeRecipientInfoGenerator(ASN1ObjectIdentifier keyAgreementOID, SubjectPublicKeyInfo originatorKeyInfo, ASN1ObjectIdentifier keyEncryptionOID)
27+
protected KeyAgreeRecipientInfoGenerator(ASN1ObjectIdentifier keyAgreementOID,
28+
SubjectPublicKeyInfo originatorKeyInfo, ASN1ObjectIdentifier keyEncryptionOID)
2629
{
2730
this.originatorKeyInfo = originatorKeyInfo;
2831
this.keyAgreementOID = keyAgreementOID;
2932
this.keyEncryptionOID = keyEncryptionOID;
3033
}
3134

32-
public RecipientInfo generate(GenericKey contentEncryptionKey)
33-
throws CMSException
35+
public RecipientInfo generate(GenericKey contentEncryptionKey) throws CMSException
3436
{
35-
OriginatorIdentifierOrKey originator = new OriginatorIdentifierOrKey(
36-
createOriginatorPublicKey(originatorKeyInfo));
37+
OriginatorPublicKey originatorPublicKey = createOriginatorPublicKey(originatorKeyInfo);
38+
OriginatorIdentifierOrKey originator = new OriginatorIdentifierOrKey(originatorPublicKey);
3739

38-
AlgorithmIdentifier keyEncAlg;
39-
if (CMSUtils.isDES(keyEncryptionOID.getId()) || keyEncryptionOID.equals(PKCSObjectIdentifiers.id_alg_CMSRC2wrap))
40+
ASN1Encodable keyEncAlgParams = null;
41+
if (CMSUtils.isDES(keyEncryptionOID) || PKCSObjectIdentifiers.id_alg_CMSRC2wrap.equals(keyEncryptionOID))
4042
{
41-
keyEncAlg = new AlgorithmIdentifier(keyEncryptionOID, DERNull.INSTANCE);
43+
keyEncAlgParams = DERNull.INSTANCE;
4244
}
4345
else if (CMSUtils.isGOST(keyAgreementOID))
4446
{
45-
keyEncAlg = new AlgorithmIdentifier(keyEncryptionOID, new Gost2814789KeyWrapParameters(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_A_ParamSet));
46-
}
47-
else
48-
{
49-
keyEncAlg = new AlgorithmIdentifier(keyEncryptionOID);
47+
keyEncAlgParams = new Gost2814789KeyWrapParameters(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_A_ParamSet);
5048
}
5149

52-
AlgorithmIdentifier keyAgreeAlg = new AlgorithmIdentifier(keyAgreementOID, keyEncAlg);
50+
AlgorithmIdentifier keyEncAlgorithm = new AlgorithmIdentifier(keyEncryptionOID, keyEncAlgParams);
51+
AlgorithmIdentifier keyAgreeAlgorithm = new AlgorithmIdentifier(keyAgreementOID, keyEncAlgorithm);
5352

54-
ASN1Sequence recipients = generateRecipientEncryptedKeys(keyAgreeAlg, keyEncAlg, contentEncryptionKey);
55-
byte[] userKeyingMaterial = getUserKeyingMaterial(keyAgreeAlg);
53+
ASN1Sequence recipients = generateRecipientEncryptedKeys(keyAgreeAlgorithm, keyEncAlgorithm, contentEncryptionKey);
5654

57-
if (userKeyingMaterial != null)
58-
{
59-
return new RecipientInfo(new KeyAgreeRecipientInfo(originator, new DEROctetString(userKeyingMaterial),
60-
keyAgreeAlg, recipients));
61-
}
62-
else
63-
{
64-
return new RecipientInfo(new KeyAgreeRecipientInfo(originator, null, keyAgreeAlg, recipients));
65-
}
55+
ASN1OctetString ukm = DEROctetString.fromContentsOptional(getUserKeyingMaterial(keyAgreeAlgorithm));
56+
57+
return new RecipientInfo(new KeyAgreeRecipientInfo(originator, ukm, keyAgreeAlgorithm, recipients));
6658
}
6759

6860
protected OriginatorPublicKey createOriginatorPublicKey(SubjectPublicKeyInfo originatorKeyInfo)
6961
{
70-
return new OriginatorPublicKey(
71-
originatorKeyInfo.getAlgorithm(),
72-
originatorKeyInfo.getPublicKeyData().getBytes());
62+
return new OriginatorPublicKey(originatorKeyInfo.getAlgorithm(), originatorKeyInfo.getPublicKeyData());
7363
}
7464

75-
protected abstract ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeAlgorithm, AlgorithmIdentifier keyEncAlgorithm, GenericKey contentEncryptionKey)
76-
throws CMSException;
77-
78-
protected abstract byte[] getUserKeyingMaterial(AlgorithmIdentifier keyAgreeAlgorithm)
79-
throws CMSException;
65+
protected abstract ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeAlgorithm,
66+
AlgorithmIdentifier keyEncAlgorithm, GenericKey contentEncryptionKey) throws CMSException;
8067

81-
}
68+
protected abstract byte[] getUserKeyingMaterial(AlgorithmIdentifier keyAgreeAlgorithm) throws CMSException;
69+
}

0 commit comments

Comments
 (0)