aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/classes/sun/security/ec/ECPrivateKeyImpl.java')
-rw-r--r--src/share/classes/sun/security/ec/ECPrivateKeyImpl.java70
1 files changed, 63 insertions, 7 deletions
diff --git a/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java b/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java
index 552a15d82e..bb12cb8283 100644
--- a/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java
+++ b/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -64,6 +64,7 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey {
private static final long serialVersionUID = 88695385615075129L;
private BigInteger s; // private value
+ private byte[] arrayS; // private value as a little-endian array
private ECParameterSpec params;
/**
@@ -81,13 +82,25 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey {
throws InvalidKeyException {
this.s = s;
this.params = params;
- // generate the encoding
+ makeEncoding(s);
+
+ }
+
+ ECPrivateKeyImpl(byte[] s, ECParameterSpec params)
+ throws InvalidKeyException {
+ this.arrayS = s.clone();
+ this.params = params;
+ makeEncoding(s);
+ }
+
+ private void makeEncoding(byte[] s) throws InvalidKeyException {
algid = new AlgorithmId
- (AlgorithmId.EC_oid, ECParameters.getAlgorithmParameters(params));
+ (AlgorithmId.EC_oid, ECParameters.getAlgorithmParameters(params));
try {
DerOutputStream out = new DerOutputStream();
out.putInteger(1); // version 1
- byte[] privBytes = ECUtil.trimZeroes(s.toByteArray());
+ byte[] privBytes = s.clone();
+ ArrayUtil.reverse(privBytes);
out.putOctetString(privBytes);
DerValue val =
new DerValue(DerValue.tag_Sequence, out.toByteArray());
@@ -98,6 +111,31 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey {
}
}
+ private void makeEncoding(BigInteger s) throws InvalidKeyException {
+ algid = new AlgorithmId
+ (AlgorithmId.EC_oid, ECParameters.getAlgorithmParameters(params));
+ try {
+ byte[] sArr = s.toByteArray();
+ // convert to fixed-length array
+ int numOctets = (params.getOrder().bitLength() + 7) / 8;
+ byte[] sOctets = new byte[numOctets];
+ int inPos = Math.max(sArr.length - sOctets.length, 0);
+ int outPos = Math.max(sOctets.length - sArr.length, 0);
+ int length = Math.min(sArr.length, sOctets.length);
+ System.arraycopy(sArr, inPos, sOctets, outPos, length);
+
+ DerOutputStream out = new DerOutputStream();
+ out.putInteger(1); // version 1
+ out.putOctetString(sOctets);
+ DerValue val =
+ new DerValue(DerValue.tag_Sequence, out.toByteArray());
+ key = val.toByteArray();
+ } catch (IOException exc) {
+ // should never occur
+ throw new InvalidKeyException(exc);
+ }
+ }
+
// see JCA doc
public String getAlgorithm() {
return "EC";
@@ -105,9 +143,26 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey {
// see JCA doc
public BigInteger getS() {
+ if (s == null) {
+ byte[] arrCopy = arrayS.clone();
+ ArrayUtil.reverse(arrCopy);
+ s = new BigInteger(1, arrCopy);
+ }
return s;
}
+ public byte[] getArrayS() {
+ if (arrayS == null) {
+ byte[] arr = getS().toByteArray();
+ ArrayUtil.reverse(arr);
+ int byteLength = (params.getOrder().bitLength() + 7) / 8;
+ arrayS = new byte[byteLength];
+ int length = Math.min(byteLength, arr.length);
+ System.arraycopy(arr, 0, arrayS, 0, length);
+ }
+ return arrayS.clone();
+ }
+
// see JCA doc
public ECParameterSpec getParams() {
return params;
@@ -129,12 +184,13 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey {
throw new IOException("Version must be 1");
}
byte[] privData = data.getOctetString();
- s = new BigInteger(1, privData);
+ ArrayUtil.reverse(privData);
+ arrayS = privData;
while (data.available() != 0) {
DerValue value = data.getDerValue();
- if (value.isContextSpecific((byte)0)) {
+ if (value.isContextSpecific((byte) 0)) {
// ignore for now
- } else if (value.isContextSpecific((byte)1)) {
+ } else if (value.isContextSpecific((byte) 1)) {
// ignore for now
} else {
throw new InvalidKeyException("Unexpected value: " + value);