44
44
import javax .crypto .SecretKeyFactory ;
45
45
import javax .crypto .spec .PBEKeySpec ;
46
46
47
+ import org .jspecify .annotations .Nullable ;
48
+
47
49
import org .springframework .boot .buildpack .platform .docker .ssl .PemPrivateKeyParser .DerElement .TagType ;
48
50
import org .springframework .boot .buildpack .platform .docker .ssl .PemPrivateKeyParser .DerElement .ValueType ;
49
51
import org .springframework .util .Assert ;
@@ -119,6 +121,7 @@ private static PKCS8EncodedKeySpec createKeySpecForPkcs1Rsa(byte[] bytes, String
119
121
120
122
private static PKCS8EncodedKeySpec createKeySpecForSec1Ec (byte [] bytes , String password ) {
121
123
DerElement ecPrivateKey = DerElement .of (bytes );
124
+ Assert .state (ecPrivateKey != null , "Unable to find private key" );
122
125
Assert .state (ecPrivateKey .isType (ValueType .ENCODED , TagType .SEQUENCE ),
123
126
"Key spec should be an ASN.1 encoded sequence" );
124
127
DerElement version = DerElement .of (ecPrivateKey .getContents ());
@@ -133,7 +136,7 @@ private static PKCS8EncodedKeySpec createKeySpecForSec1Ec(byte[] bytes, String p
133
136
return createKeySpecForAlgorithm (bytes , ELLIPTIC_CURVE_ALGORITHM , getEcParameters (parameters ));
134
137
}
135
138
136
- private static EncodedOid getEcParameters (DerElement parameters ) {
139
+ private static EncodedOid getEcParameters (@ Nullable DerElement parameters ) {
137
140
if (parameters == null ) {
138
141
return ELLIPTIC_CURVE_384_BIT ;
139
142
}
@@ -145,7 +148,7 @@ private static EncodedOid getEcParameters(DerElement parameters) {
145
148
}
146
149
147
150
private static PKCS8EncodedKeySpec createKeySpecForAlgorithm (byte [] bytes , EncodedOid algorithm ,
148
- EncodedOid parameters ) {
151
+ @ Nullable EncodedOid parameters ) {
149
152
try {
150
153
DerEncoder encoder = new DerEncoder ();
151
154
encoder .integer (0x00 ); // Version 0
@@ -163,6 +166,7 @@ private static PKCS8EncodedKeySpec createKeySpecForAlgorithm(byte[] bytes, Encod
163
166
164
167
private static PKCS8EncodedKeySpec createKeySpecForPkcs8 (byte [] bytes , String password ) {
165
168
DerElement ecPrivateKey = DerElement .of (bytes );
169
+ Assert .state (ecPrivateKey != null , "Unable to find private key" );
166
170
Assert .state (ecPrivateKey .isType (ValueType .ENCODED , TagType .SEQUENCE ),
167
171
"Key spec should be an ASN.1 encoded sequence" );
168
172
DerElement version = DerElement .of (ecPrivateKey .getContents ());
@@ -187,7 +191,7 @@ private static PKCS8EncodedKeySpec createKeySpecForPkcs8Encrypted(byte[] bytes,
187
191
* @param text the text to parse
188
192
* @return the parsed private key
189
193
*/
190
- static PrivateKey parse (String text ) {
194
+ static @ Nullable PrivateKey parse (String text ) {
191
195
return parse (text , null );
192
196
}
193
197
@@ -198,7 +202,7 @@ static PrivateKey parse(String text) {
198
202
* @param password the password used to decrypt an encrypted private key
199
203
* @return the parsed private key
200
204
*/
201
- static PrivateKey parse (String text , String password ) {
205
+ static @ Nullable PrivateKey parse (@ Nullable String text , @ Nullable String password ) {
202
206
if (text == null ) {
203
207
return null ;
204
208
}
@@ -223,18 +227,18 @@ private static class PemParser {
223
227
224
228
private final Pattern pattern ;
225
229
226
- private final BiFunction <byte [], String , PKCS8EncodedKeySpec > keySpecFactory ;
230
+ private final BiFunction <byte [], @ Nullable String , PKCS8EncodedKeySpec > keySpecFactory ;
227
231
228
232
private final String [] algorithms ;
229
233
230
- PemParser (String header , String footer , BiFunction < byte [], String , PKCS8EncodedKeySpec > keySpecFactory ,
231
- String ... algorithms ) {
234
+ PemParser (String header , String footer ,
235
+ BiFunction < byte [], @ Nullable String , PKCS8EncodedKeySpec > keySpecFactory , String ... algorithms ) {
232
236
this .pattern = Pattern .compile (header + BASE64_TEXT + footer , Pattern .CASE_INSENSITIVE );
233
237
this .keySpecFactory = keySpecFactory ;
234
238
this .algorithms = algorithms ;
235
239
}
236
240
237
- PrivateKey parse (String text , String password ) {
241
+ @ Nullable PrivateKey parse (String text , @ Nullable String password ) {
238
242
Matcher matcher = this .pattern .matcher (text );
239
243
return (!matcher .find ()) ? null : parse (decodeBase64 (matcher .group (BASE64_TEXT_GROUP )), password );
240
244
}
@@ -244,7 +248,7 @@ private static byte[] decodeBase64(String content) {
244
248
return Base64 .getDecoder ().decode (contentBytes );
245
249
}
246
250
247
- private PrivateKey parse (byte [] bytes , String password ) {
251
+ private @ Nullable PrivateKey parse (byte [] bytes , @ Nullable String password ) {
248
252
PKCS8EncodedKeySpec keySpec = this .keySpecFactory .apply (bytes , password );
249
253
if (keySpec .getAlgorithm () != null ) {
250
254
try {
@@ -276,7 +280,7 @@ static class DerEncoder {
276
280
277
281
private final ByteArrayOutputStream stream = new ByteArrayOutputStream ();
278
282
279
- void objectIdentifier (EncodedOid encodedOid ) throws IOException {
283
+ void objectIdentifier (@ Nullable EncodedOid encodedOid ) throws IOException {
280
284
int code = (encodedOid != null ) ? 0x06 : 0x05 ;
281
285
codeLengthBytes (code , (encodedOid != null ) ? encodedOid .toByteArray () : null );
282
286
}
@@ -293,7 +297,7 @@ void sequence(byte[] bytes) throws IOException {
293
297
codeLengthBytes (0x30 , bytes );
294
298
}
295
299
296
- void codeLengthBytes (int code , byte [] bytes ) throws IOException {
300
+ void codeLengthBytes (int code , byte @ Nullable [] bytes ) throws IOException {
297
301
this .stream .write (code );
298
302
int length = (bytes != null ) ? bytes .length : 0 ;
299
303
if (length <= 127 ) {
@@ -316,7 +320,7 @@ void codeLengthBytes(int code, byte[] bytes) throws IOException {
316
320
}
317
321
}
318
322
319
- private static byte [] bytes (int ... elements ) {
323
+ private static byte @ Nullable [] bytes (int @ Nullable ... elements ) {
320
324
if (elements == null ) {
321
325
return null ;
322
326
}
@@ -405,11 +409,11 @@ ByteBuffer getContents() {
405
409
return this .contents ;
406
410
}
407
411
408
- static DerElement of (byte [] bytes ) {
412
+ static @ Nullable DerElement of (byte [] bytes ) {
409
413
return of (ByteBuffer .wrap (bytes ));
410
414
}
411
415
412
- static DerElement of (ByteBuffer bytes ) {
416
+ static @ Nullable DerElement of (ByteBuffer bytes ) {
413
417
return (bytes .remaining () > 0 ) ? new DerElement (bytes ) : null ;
414
418
}
415
419
@@ -444,7 +448,7 @@ static class Pkcs8PrivateKeyDecryptor {
444
448
445
449
public static final String PBES2_ALGORITHM = "PBES2" ;
446
450
447
- static PKCS8EncodedKeySpec decrypt (byte [] bytes , String password ) {
451
+ static PKCS8EncodedKeySpec decrypt (byte [] bytes , @ Nullable String password ) {
448
452
Assert .state (password != null , "Password is required for an encrypted private key" );
449
453
try {
450
454
EncryptedPrivateKeyInfo keyInfo = new EncryptedPrivateKeyInfo (bytes );
@@ -461,7 +465,7 @@ static PKCS8EncodedKeySpec decrypt(byte[] bytes, String password) {
461
465
}
462
466
}
463
467
464
- private static String getEncryptionAlgorithm (AlgorithmParameters algParameters , String algName ) {
468
+ private static String getEncryptionAlgorithm (@ Nullable AlgorithmParameters algParameters , String algName ) {
465
469
if (algParameters != null && PBES2_ALGORITHM .equals (algName )) {
466
470
return algParameters .toString ();
467
471
}
0 commit comments