@@ -43,6 +43,7 @@ final class XDHPrivateKeyImpl extends PKCS8Key implements XECPrivateKey, Seriali
43
43
private transient Optional <byte []> scalar ;
44
44
private transient NamedParameterSpec params ;
45
45
private CURVE curve ;
46
+ private byte [] k ; // The raw key bytes, without OctetString or DER encoded
46
47
BigInteger bi1 ; // parameter used in FFDHE
47
48
BigInteger bi2 ; // parameter used in FFDHE
48
49
BigInteger bi3 ; // parameter used in FFDHE
@@ -55,9 +56,10 @@ final class XDHPrivateKeyImpl extends PKCS8Key implements XECPrivateKey, Seriali
55
56
private transient XECKey xecKey = null ;
56
57
57
58
private void setFieldsFromXeckey () throws Exception {
58
- if (this .key == null ) {
59
- this .key = extractPrivateKeyFromOCK (xecKey .getPrivateKeyBytes ()); // Extract key from GSKit and sets params
60
- this .scalar = Optional .of (key );
59
+ if (k == null ) {
60
+ k = extractPrivateKeyFromOCK (xecKey .getPrivateKeyBytes ()); // Extract key from GSKit and sets params
61
+ setPKCS8KeyByte (k );
62
+ this .scalar = Optional .of (k );
61
63
this .algid = CurveUtil .getAlgId (this .params .getName ());
62
64
}
63
65
}
@@ -97,7 +99,7 @@ public XDHPrivateKeyImpl(OpenJCEPlusProvider provider, byte[] encoded)
97
99
// to fit with GSKit and sets params
98
100
int encodingSize = CurveUtil .getDEREncodingSize (curve );
99
101
this .xecKey = XECKey .createPrivateKey (provider .getOCKContext (), alteredEncoded , encodingSize );
100
- this .scalar = Optional .of (this . key );
102
+ this .scalar = Optional .of (k );
101
103
} catch (Exception exception ) {
102
104
InvalidKeyException ike = new InvalidKeyException ("Failed to create XEC private key" );
103
105
provider .setOCKExceptionCause (ike , exception );
@@ -138,9 +140,9 @@ public XDHPrivateKeyImpl(OpenJCEPlusProvider provider, AlgorithmParameterSpec pa
138
140
this .provider = provider ;
139
141
this .scalar = scalar ;
140
142
if (scalar != null )
141
- this . key = scalar .get ();
143
+ k = scalar .get ();
142
144
try {
143
- if (this . key == null ) {
145
+ if (k == null ) {
144
146
int keySize = CurveUtil .getCurveSize (curve );
145
147
this .xecKey = XECKey .generateKeyPair (provider .getOCKContext (), this .curve .ordinal (), keySize );
146
148
} else {
@@ -149,6 +151,7 @@ public XDHPrivateKeyImpl(OpenJCEPlusProvider provider, AlgorithmParameterSpec pa
149
151
int encodingSize = CurveUtil .getDEREncodingSize (curve );
150
152
this .xecKey = XECKey .createPrivateKey (provider .getOCKContext (), der , encodingSize );
151
153
}
154
+ setPKCS8KeyByte (k );
152
155
} catch (Exception exception ) {
153
156
InvalidParameterException ike = new InvalidParameterException (
154
157
"Failed to create XEC private key" );
@@ -178,7 +181,7 @@ private byte[] buildOCKPrivateKeyBytes() throws IOException {
178
181
179
182
// Adding Key
180
183
DerOutputStream keyOctetString = new DerOutputStream ();
181
- keyOctetString .putOctetString (key );
184
+ keyOctetString .putOctetString (k );
182
185
mainSeq .putOctetString (keyOctetString .toByteArray ());
183
186
184
187
// Wrapping up in a sequence
@@ -316,20 +319,21 @@ private byte[] processEncodedPrivateKey(byte[] encoded) throws IOException {
316
319
// XDH private key in SunEC new Java 17 design requires [octet-string[octet-string[key-bytes]]] format,
317
320
// otherwise, it causes interop issue.
318
321
if (isCorrectlyFormedOctetString (keyBytes )) {
319
- this . key = derStream .getOctetString (); // We know we are working with the format [octet-string[octet-string[key-bytes]]]
322
+ k = derStream .getOctetString (); // We know we are working with the format [octet-string[octet-string[key-bytes]]]
320
323
} else {
321
- this . key = keyBytes ; // Try J11 format [octet-string[key-bytes]]
324
+ k = keyBytes ; // Try J11 format [octet-string[key-bytes]]
322
325
}
323
326
} catch (Exception e ) {
324
327
//e.printStackTrace();
325
- this . key = keyBytes ; // Try J11 format [octet-string[key-bytes]]
328
+ k = keyBytes ; // Try J11 format [octet-string[key-bytes]]
326
329
}
330
+ setPKCS8KeyByte (k );
327
331
try (DerOutputStream encodedKey = new DerOutputStream ()) {
328
332
if (CurveUtil .isFFDHE (this .curve )) {
329
- BigInteger octetStringAsBigInt = new BigInteger (this . key );
333
+ BigInteger octetStringAsBigInt = new BigInteger (k );
330
334
encodedKey .putInteger (octetStringAsBigInt ); // Put in another octet string
331
335
} else {
332
- encodedKey .putOctetString (this . key ); // Put in another octet string
336
+ encodedKey .putOctetString (k ); // Put in another octet string
333
337
}
334
338
outStream .putOctetString (encodedKey .toByteArray ());
335
339
}
@@ -399,7 +403,7 @@ public byte[] getKeyBytes() {
399
403
} catch (Exception exception ) {
400
404
this .exception = exception ;
401
405
}
402
- return this . key .clone ();
406
+ return k .clone ();
403
407
}
404
408
405
409
@ Override
@@ -491,10 +495,10 @@ public void encode(OutputStream os) throws IOException {
491
495
bytes .write (oidTmp .toByteArray ());
492
496
493
497
// encode encrypted key
494
- if (this . key != null ) {
498
+ if (k != null ) {
495
499
// XDH private key in SunEC and new Java 17 design requires [octet-string[octer-string[key-bytes]]] format,
496
500
// otherwise, it causes interop issue. JCK issue 569
497
- bytes .putOctetString (new DerValue (DerValue .tag_OctetString , this . key ).toByteArray ());
501
+ bytes .putOctetString (new DerValue (DerValue .tag_OctetString , k ).toByteArray ());
498
502
}
499
503
500
504
// wrap everything into a SEQUENCE
@@ -521,6 +525,8 @@ public void destroy() throws DestroyFailedException {
521
525
}
522
526
if (!destroyed ) {
523
527
destroyed = true ;
528
+ if (k != null )
529
+ Arrays .fill (k , (byte ) 0x00 );
524
530
if (this .key != null )
525
531
Arrays .fill (this .key , (byte ) 0x00 );
526
532
this .xecKey = null ;
@@ -545,4 +551,18 @@ private void checkDestroyed() {
545
551
protected Object writeReplace () throws java .io .ObjectStreamException {
546
552
return new KeyRep (KeyRep .Type .PRIVATE , getAlgorithm (), getFormat (), getEncoded ());
547
553
}
554
+
555
+ /**
556
+ * Set the PKCS8Key key object.
557
+ *
558
+ * @param k The raw key bytes, without OctetString or DER encoded.
559
+ * @throws IOException
560
+ */
561
+ private void setPKCS8KeyByte (byte [] k ) throws IOException {
562
+ if (Integer .parseInt (provider .getJavaVersionStr ()) <= 11 ) {
563
+ this .key = k ;
564
+ } else {
565
+ this .key = new DerValue (DerValue .tag_OctetString , k ).toByteArray ();
566
+ }
567
+ }
548
568
}
0 commit comments