diff options
Diffstat (limited to 'src/share/classes/sun/security/ec/ECPrivateKeyImpl.java')
-rw-r--r-- | src/share/classes/sun/security/ec/ECPrivateKeyImpl.java | 70 |
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); |