8042967: Add variant of DSA Signature algorithms that do not ASN.1 encode the signature bytes
Reviewed-by: mullan
--- a/jdk/src/java.base/share/classes/sun/security/provider/DSA.java Tue Feb 17 09:18:27 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/provider/DSA.java Tue Feb 17 10:48:24 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -33,14 +33,11 @@
import java.security.*;
import java.security.SecureRandom;
import java.security.interfaces.*;
-import java.security.spec.DSAParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
import sun.security.util.Debug;
import sun.security.util.DerValue;
import sun.security.util.DerInputStream;
import sun.security.util.DerOutputStream;
-import sun.security.x509.AlgIdDSA;
import sun.security.jca.JCAUtil;
/**
@@ -85,13 +82,28 @@
/* The message digest object used */
private final MessageDigest md;
+ /* The format. true for the IEEE P1363 format. false (default) for ASN.1 */
+ private final boolean p1363Format;
+
/**
* Construct a blank DSA object. It must be
* initialized before being usable for signing or verifying.
*/
DSA(MessageDigest md) {
+ this(md, false);
+ }
+
+ /**
+ * Construct a blank DSA object that will use the specified
+ * signature format. {@code p1363Format} should be {@code true} to
+ * use the IEEE P1363 format. If {@code p1363Format} is {@code false},
+ * the DER-encoded ASN.1 format will used. The DSA object must be
+ * initialized before being usable for signing or verifying.
+ */
+ DSA(MessageDigest md, boolean p1363Format) {
super();
this.md = md;
+ this.p1363Format = p1363Format;
}
/**
@@ -178,12 +190,16 @@
/**
- * Sign all the data thus far updated. The signature is formatted
+ * Sign all the data thus far updated. The signature format is
+ * determined by {@code p1363Format}. If {@code p1363Format} is
+ * {@code false} (the default), then the signature is formatted
* according to the Canonical Encoding Rules, returned as a DER
- * sequence of Integer, r and s.
+ * sequence of Integers, r and s. If {@code p1363Format} is
+ * {@code false}, the signature is returned in the IEEE P1363
+ * format, which is the concatenation or r and s.
*
- * @return a signature block formatted according to the Canonical
- * Encoding Rules.
+ * @return a signature block formatted according to the format
+ * indicated by {@code p1363Format}
*
* @exception SignatureException if the signature object was not
* properly initialized, or if another exception occurs.
@@ -196,24 +212,48 @@
BigInteger r = generateR(presetP, presetQ, presetG, k);
BigInteger s = generateS(presetX, presetQ, r, k);
- try {
- DerOutputStream outseq = new DerOutputStream(100);
- outseq.putInteger(r);
- outseq.putInteger(s);
- DerValue result = new DerValue(DerValue.tag_Sequence,
- outseq.toByteArray());
+ if (p1363Format) {
+ // Return the concatenation of r and s
+ byte[] rBytes = r.toByteArray();
+ byte[] sBytes = s.toByteArray();
+
+ int size = presetQ.bitLength() / 8;
+ byte[] outseq = new byte[size * 2];
+
+ int rLength = rBytes.length;
+ int sLength = sBytes.length;
+ int i;
+ for (i = rLength; i > 0 && rBytes[rLength - i] == 0; i--);
+
+ int j;
+ for (j = sLength;
+ j > 0 && sBytes[sLength - j] == 0; j--);
- return result.toByteArray();
+ System.arraycopy(rBytes, rLength - i, outseq, size - i, i);
+ System.arraycopy(sBytes, sLength - j, outseq, size * 2 - j, j);
- } catch (IOException e) {
- throw new SignatureException("error encoding signature");
+ return outseq;
+ } else {
+ // Return the DER-encoded ASN.1 form
+ try {
+ DerOutputStream outseq = new DerOutputStream(100);
+ outseq.putInteger(r);
+ outseq.putInteger(s);
+ DerValue result = new DerValue(DerValue.tag_Sequence,
+ outseq.toByteArray());
+
+ return result.toByteArray();
+
+ } catch (IOException e) {
+ throw new SignatureException("error encoding signature");
+ }
}
}
/**
* Verify all the data thus far updated.
*
- * @param signature the alledged signature, encoded using the
+ * @param signature the alleged signature, encoded using the
* Canonical Encoding Rules, as a sequence of integers, r and s.
*
* @exception SignatureException if the signature object was not
@@ -230,8 +270,13 @@
/**
* Verify all the data thus far updated.
*
- * @param signature the alledged signature, encoded using the
- * Canonical Encoding Rules, as a sequence of integers, r and s.
+ * @param signature the alleged signature, encoded using the
+ * format indicated by {@code p1363Format}. If {@code p1363Format}
+ * is {@code false} (the default), then the signature is formatted
+ * according to the Canonical Encoding Rules, as a DER sequence of
+ * Integers, r and s. If {@code p1363Format} is {@code false},
+ * the signature is in the IEEE P1363 format, which is the
+ * concatenation or r and s.
*
* @param offset the offset to start from in the array of bytes.
*
@@ -248,16 +293,28 @@
BigInteger r = null;
BigInteger s = null;
- // first decode the signature.
- try {
- DerInputStream in = new DerInputStream(signature, offset, length);
- DerValue[] values = in.getSequence(2);
- r = values[0].getBigInteger();
- s = values[1].getBigInteger();
+ if (p1363Format) {
+ if ((length & 1) == 1) {
+ // length of signature byte array should be even
+ throw new SignatureException("invalid signature format");
+ }
+ int mid = length/2;
+ r = new BigInteger(Arrays.copyOfRange(signature, 0, mid));
+ s = new BigInteger(Arrays.copyOfRange(signature, mid, length));
+ } else {
+ // first decode the signature.
+ try {
+ DerInputStream in = new DerInputStream(signature, offset,
+ length);
+ DerValue[] values = in.getSequence(2);
- } catch (IOException e) {
- throw new SignatureException("invalid encoding for signature");
+ r = values[0].getBigInteger();
+ s = values[1].getBigInteger();
+
+ } catch (IOException e) {
+ throw new SignatureException("invalid encoding for signature");
+ }
}
// some implementations do not correctly encode values in the ASN.1
@@ -421,6 +478,15 @@
}
/**
+ * SHA224withDSA implementation that uses the IEEE P1363 format.
+ */
+ public static final class SHA224withDSAinP1363Format extends DSA {
+ public SHA224withDSAinP1363Format() throws NoSuchAlgorithmException {
+ super(MessageDigest.getInstance("SHA-224"), true);
+ }
+ }
+
+ /**
* Standard SHA256withDSA implementation as defined in FIPS186-3.
*/
public static final class SHA256withDSA extends DSA {
@@ -429,6 +495,15 @@
}
}
+ /**
+ * SHA256withDSA implementation that uses the IEEE P1363 format.
+ */
+ public static final class SHA256withDSAinP1363Format extends DSA {
+ public SHA256withDSAinP1363Format() throws NoSuchAlgorithmException {
+ super(MessageDigest.getInstance("SHA-256"), true);
+ }
+ }
+
static class LegacyDSA extends DSA {
/* The random seed used to generate k */
private int[] kSeed;
@@ -441,7 +516,12 @@
private int[] kSeedLast;
public LegacyDSA(MessageDigest md) throws NoSuchAlgorithmException {
- super(md);
+ this(md, false);
+ }
+
+ private LegacyDSA(MessageDigest md, boolean p1363Format)
+ throws NoSuchAlgorithmException {
+ super(md, p1363Format);
}
@Deprecated
@@ -636,6 +716,9 @@
}
}
+ /**
+ * Standard SHA1withDSA implementation.
+ */
public static final class SHA1withDSA extends LegacyDSA {
public SHA1withDSA() throws NoSuchAlgorithmException {
super(MessageDigest.getInstance("SHA-1"));
@@ -643,13 +726,22 @@
}
/**
- * RawDSA implementation.
+ * SHA1withDSA implementation that uses the IEEE P1363 format.
+ */
+ public static final class SHA1withDSAinP1363Format extends LegacyDSA {
+ public SHA1withDSAinP1363Format() throws NoSuchAlgorithmException {
+ super(MessageDigest.getInstance("SHA-1"), true);
+ }
+ }
+
+ /**
+ * Raw DSA.
*
- * RawDSA requires the data to be exactly 20 bytes long. If it is
+ * Raw DSA requires the data to be exactly 20 bytes long. If it is
* not, a SignatureException is thrown when sign()/verify() is called
* per JCA spec.
*/
- public static final class RawDSA extends LegacyDSA {
+ static class Raw extends LegacyDSA {
// Internal special-purpose MessageDigest impl for RawDSA
// Only override whatever methods used
// NOTE: no clone support
@@ -719,8 +811,27 @@
}
}
+ private Raw(boolean p1363Format) throws NoSuchAlgorithmException {
+ super(new NullDigest20(), p1363Format);
+ }
+
+ }
+
+ /**
+ * Standard Raw DSA implementation.
+ */
+ public static final class RawDSA extends Raw {
public RawDSA() throws NoSuchAlgorithmException {
- super(new NullDigest20());
+ super(false);
+ }
+ }
+
+ /**
+ * Raw DSA implementation that uses the IEEE P1363 format.
+ */
+ public static final class RawDSAinP1363Format extends Raw {
+ public RawDSAinP1363Format() throws NoSuchAlgorithmException {
+ super(true);
}
}
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/SunEntries.java Tue Feb 17 09:18:27 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/provider/SunEntries.java Tue Feb 17 10:48:24 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -130,6 +130,15 @@
map.put("Signature.SHA256withDSA",
"sun.security.provider.DSA$SHA256withDSA");
+ map.put("Signature.SHA1withDSAinP1363Format",
+ "sun.security.provider.DSA$SHA1withDSAinP1363Format");
+ map.put("Signature.NONEwithDSAinP1363Format",
+ "sun.security.provider.DSA$RawDSAinP1363Format");
+ map.put("Signature.SHA224withDSAinP1363Format",
+ "sun.security.provider.DSA$SHA224withDSAinP1363Format");
+ map.put("Signature.SHA256withDSAinP1363Format",
+ "sun.security.provider.DSA$SHA256withDSAinP1363Format");
+
String dsaKeyClasses = "java.security.interfaces.DSAPublicKey" +
"|java.security.interfaces.DSAPrivateKey";
map.put("Signature.SHA1withDSA SupportedKeyClasses", dsaKeyClasses);
--- a/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Tue Feb 17 09:18:27 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Tue Feb 17 10:48:24 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, 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
@@ -171,8 +171,9 @@
// OAEPWith<digest>And<mgf>Padding
// <digest>with<encryption>
// <digest>with<encryption>and<mgf>
+ // <digest>with<encryption>in<format>
Pattern pattern =
- Pattern.compile("with|and", Pattern.CASE_INSENSITIVE);
+ Pattern.compile("with|and|in", Pattern.CASE_INSENSITIVE);
String[] tokens = pattern.split(transTocken);
for (String token : tokens) {
--- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java Tue Feb 17 09:18:27 2015 -0800
+++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java Tue Feb 17 10:48:24 2015 -0800
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
*/
/*
* $Id: DOMSignatureMethod.java 1333415 2012-05-03 12:03:51Z coheigea $
@@ -111,6 +111,34 @@
}
}
+ /**
+ * Returns the signature bytes with any additional formatting
+ * necessary for the signature algorithm used. For RSA signatures,
+ * no changes are required, and this method should simply return
+ * back {@code sig}. For DSA and ECDSA, this method should return the
+ * signature in the IEEE P1363 format, the concatenation of r and s.
+ *
+ * @param key the key used to sign
+ * @param sig the signature returned by {@code Signature.sign()}
+ * @return the formatted signature
+ * @throws IOException
+ */
+ abstract byte[] postSignFormat(Key key, byte[] sig) throws IOException;
+
+ /**
+ * Returns the signature bytes with any conversions that are necessary
+ * before the signature can be verified. For RSA signatures,
+ * no changes are required, and this method should simply
+ * return back {@code sig}. For DSA and ECDSA, this method should
+ * return the signature in the DER-encoded ASN.1 format.
+ *
+ * @param key the key used to sign
+ * @param sig the signature
+ * @return the formatted signature
+ * @throws IOException
+ */
+ abstract byte[] preVerifyFormat(Key key, byte[] sig) throws IOException;
+
static SignatureMethod unmarshal(Element smElem) throws MarshalException {
String alg = DOMUtils.getAttributeValue(smElem, "Algorithm");
if (alg.equals(SignatureMethod.RSA_SHA1)) {
@@ -151,6 +179,23 @@
return params;
}
+ /**
+ * Returns an instance of Signature from the specified Provider.
+ * The algorithm is specified by the {@code getJCAAlgorithm()} method.
+ *
+ * @param p the Provider to use
+ * @return an instance of Signature implementing the algorithm
+ * specified by {@code getJCAAlgorithm()}
+ * @throws NoSuchAlgorithmException if the Provider does not support the
+ * signature algorithm
+ */
+ Signature getSignature(Provider p)
+ throws NoSuchAlgorithmException {
+ return (p == null)
+ ? Signature.getInstance(getJCAAlgorithm())
+ : Signature.getInstance(getJCAAlgorithm(), p);
+ }
+
boolean verify(Key key, SignedInfo si, byte[] sig,
XMLValidateContext context)
throws InvalidKeyException, SignatureException, XMLSignatureException
@@ -163,38 +208,30 @@
throw new InvalidKeyException("key must be PublicKey");
}
if (signature == null) {
+ Provider p = (Provider)context.getProperty(
+ "org.jcp.xml.dsig.internal.dom.SignatureProvider");
try {
- Provider p = (Provider)context.getProperty
- ("org.jcp.xml.dsig.internal.dom.SignatureProvider");
- signature = (p == null)
- ? Signature.getInstance(getJCAAlgorithm())
- : Signature.getInstance(getJCAAlgorithm(), p);
+ signature = getSignature(p);
} catch (NoSuchAlgorithmException nsae) {
throw new XMLSignatureException(nsae);
}
}
signature.initVerify((PublicKey)key);
if (log.isLoggable(java.util.logging.Level.FINE)) {
- log.log(java.util.logging.Level.FINE, "Signature provider:" + signature.getProvider());
+ log.log(java.util.logging.Level.FINE,
+ "Signature provider:" + signature.getProvider());
log.log(java.util.logging.Level.FINE, "verifying with key: " + key);
}
((DOMSignedInfo)si).canonicalize(context,
new SignerOutputStream(signature));
-
+ byte[] s;
try {
- Type type = getAlgorithmType();
- if (type == Type.DSA) {
- int size = ((DSAKey)key).getParams().getQ().bitLength();
- return signature.verify(JavaUtils.convertDsaXMLDSIGtoASN1(sig,
- size/8));
- } else if (type == Type.ECDSA) {
- return signature.verify(SignatureECDSA.convertXMLDSIGtoASN1(sig));
- } else {
- return signature.verify(sig);
- }
+ // Do any necessary format conversions
+ s = preVerifyFormat(key, sig);
} catch (IOException ioe) {
throw new XMLSignatureException(ioe);
}
+ return signature.verify(s);
}
byte[] sign(Key key, SignedInfo si, XMLSignContext context)
@@ -208,19 +245,18 @@
throw new InvalidKeyException("key must be PrivateKey");
}
if (signature == null) {
+ Provider p = (Provider)context.getProperty(
+ "org.jcp.xml.dsig.internal.dom.SignatureProvider");
try {
- Provider p = (Provider)context.getProperty
- ("org.jcp.xml.dsig.internal.dom.SignatureProvider");
- signature = (p == null)
- ? Signature.getInstance(getJCAAlgorithm())
- : Signature.getInstance(getJCAAlgorithm(), p);
+ signature = getSignature(p);
} catch (NoSuchAlgorithmException nsae) {
throw new XMLSignatureException(nsae);
}
}
signature.initSign((PrivateKey)key);
if (log.isLoggable(java.util.logging.Level.FINE)) {
- log.log(java.util.logging.Level.FINE, "Signature provider:" + signature.getProvider());
+ log.log(java.util.logging.Level.FINE,
+ "Signature provider:" + signature.getProvider());
log.log(java.util.logging.Level.FINE, "Signing with key: " + key);
}
@@ -228,24 +264,171 @@
new SignerOutputStream(signature));
try {
- Type type = getAlgorithmType();
- if (type == Type.DSA) {
- int size = ((DSAKey)key).getParams().getQ().bitLength();
- return JavaUtils.convertDsaASN1toXMLDSIG(signature.sign(),
- size/8);
- } else if (type == Type.ECDSA) {
- return SignatureECDSA.convertASN1toXMLDSIG(signature.sign());
- } else {
- return signature.sign();
- }
- } catch (SignatureException se) {
- throw new XMLSignatureException(se);
- } catch (IOException ioe) {
- throw new XMLSignatureException(ioe);
+ // Return signature with any necessary format conversions
+ return postSignFormat(key, signature.sign());
+ } catch (SignatureException | IOException ex){
+ throw new XMLSignatureException(ex);
+ }
+ }
+
+ abstract static class AbstractRSASignatureMethod
+ extends DOMSignatureMethod {
+
+ AbstractRSASignatureMethod(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ super(params);
+ }
+
+ AbstractRSASignatureMethod(Element dmElem) throws MarshalException {
+ super(dmElem);
+ }
+
+ /**
+ * Returns {@code sig}. No extra formatting is necessary for RSA.
+ */
+ @Override
+ byte[] postSignFormat(Key key, byte[] sig) {
+ return sig;
+ }
+
+ /**
+ * Returns {@code sig}. No extra formatting is necessary for RSA.
+ */
+ @Override
+ byte[] preVerifyFormat(Key key, byte[] sig) {
+ return sig;
}
}
- static final class SHA1withRSA extends DOMSignatureMethod {
+ /**
+ * Abstract class to support signature algorithms that sign and verify
+ * signatures in the IEEE P1363 format. The P1363 format is the
+ * concatenation of r and s in DSA and ECDSA signatures, and thus, only
+ * DSA and ECDSA signature methods should extend this class. Subclasses
+ * must supply a fallback algorithm to be used when the provider does
+ * not offer signature algorithms that use the P1363 format.
+ */
+ abstract static class AbstractP1363FormatSignatureMethod
+ extends DOMSignatureMethod {
+
+ /* Set to true when the fallback algorithm is used */
+ boolean asn1;
+
+ AbstractP1363FormatSignatureMethod(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ super(params);
+ }
+
+ AbstractP1363FormatSignatureMethod(Element dmElem)
+ throws MarshalException {
+ super(dmElem);
+ }
+
+ /**
+ * Return the fallback algorithm to be used when the provider does not
+ * support signatures in the IEEE P1363 format. This algorithm should
+ * return signatures in the DER-encoded ASN.1 format.
+ */
+ abstract String getJCAFallbackAlgorithm();
+
+ /*
+ * Try to return an instance of Signature implementing signatures
+ * in the IEEE P1363 format. If the provider doesn't support the
+ * P1363 format, return an instance of Signature implementing
+ * signatures in the DER-encoded ASN.1 format.
+ */
+ @Override
+ Signature getSignature(Provider p)
+ throws NoSuchAlgorithmException {
+ try {
+ return (p == null)
+ ? Signature.getInstance(getJCAAlgorithm())
+ : Signature.getInstance(getJCAAlgorithm(), p);
+ } catch (NoSuchAlgorithmException nsae) {
+ Signature s = (p == null)
+ ? Signature.getInstance(getJCAFallbackAlgorithm())
+ : Signature.getInstance(getJCAFallbackAlgorithm(), p);
+ asn1 = true;
+ return s;
+ }
+ }
+ }
+
+ abstract static class AbstractDSASignatureMethod
+ extends AbstractP1363FormatSignatureMethod {
+
+ AbstractDSASignatureMethod(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ super(params);
+ }
+
+ AbstractDSASignatureMethod(Element dmElem) throws MarshalException {
+ super(dmElem);
+ }
+
+ @Override
+ byte[] postSignFormat(Key key, byte[] sig) throws IOException {
+ // If signature is in ASN.1 (i.e., if the fallback algorithm
+ // was used), convert the signature to the P1363 format
+ if (asn1) {
+ int size = ((DSAKey) key).getParams().getQ().bitLength();
+ return JavaUtils.convertDsaASN1toXMLDSIG(sig, size / 8);
+ } else {
+ return sig;
+ }
+ }
+
+ @Override
+ byte[] preVerifyFormat(Key key, byte[] sig) throws IOException {
+ // If signature needs to be in ASN.1 (i.e., if the fallback
+ // algorithm will be used to verify the sig), convert the signature
+ // to the ASN.1 format
+ if (asn1) {
+ int size = ((DSAKey) key).getParams().getQ().bitLength();
+ return JavaUtils.convertDsaXMLDSIGtoASN1(sig, size / 8);
+ } else {
+ return sig;
+ }
+ }
+ }
+
+ abstract static class AbstractECDSASignatureMethod
+ extends AbstractP1363FormatSignatureMethod {
+
+ AbstractECDSASignatureMethod(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ super(params);
+ }
+
+ AbstractECDSASignatureMethod(Element dmElem) throws MarshalException {
+ super(dmElem);
+ }
+
+ @Override
+ byte[] postSignFormat(Key key, byte[] sig) throws IOException {
+ // If signature is in ASN.1 (i.e., if the fallback algorithm
+ // was used), convert the signature to the P1363 format
+ if (asn1) {
+ return SignatureECDSA.convertASN1toXMLDSIG(sig);
+ } else {
+ return sig;
+ }
+ }
+
+ @Override
+ byte[] preVerifyFormat(Key key, byte[] sig) throws IOException {
+ // If signature needs to be in ASN.1 (i.e., if the fallback
+ // algorithm will be used to verify the sig), convert the signature
+ // to the ASN.1 format
+ if (asn1) {
+ return SignatureECDSA.convertXMLDSIGtoASN1(sig);
+ } else {
+ return sig;
+ }
+ }
+ }
+
+ static final class SHA1withRSA extends AbstractRSASignatureMethod {
SHA1withRSA(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
@@ -264,7 +447,7 @@
}
}
- static final class SHA256withRSA extends DOMSignatureMethod {
+ static final class SHA256withRSA extends AbstractRSASignatureMethod {
SHA256withRSA(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
@@ -283,7 +466,7 @@
}
}
- static final class SHA384withRSA extends DOMSignatureMethod {
+ static final class SHA384withRSA extends AbstractRSASignatureMethod {
SHA384withRSA(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
@@ -302,7 +485,7 @@
}
}
- static final class SHA512withRSA extends DOMSignatureMethod {
+ static final class SHA512withRSA extends AbstractRSASignatureMethod {
SHA512withRSA(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
@@ -321,7 +504,7 @@
}
}
- static final class SHA1withDSA extends DOMSignatureMethod {
+ static final class SHA1withDSA extends AbstractDSASignatureMethod {
SHA1withDSA(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
@@ -333,6 +516,9 @@
return SignatureMethod.DSA_SHA1;
}
String getJCAAlgorithm() {
+ return "SHA1withDSAinP1363Format";
+ }
+ String getJCAFallbackAlgorithm() {
return "SHA1withDSA";
}
Type getAlgorithmType() {
@@ -340,7 +526,7 @@
}
}
- static final class SHA256withDSA extends DOMSignatureMethod {
+ static final class SHA256withDSA extends AbstractDSASignatureMethod {
SHA256withDSA(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
@@ -352,6 +538,9 @@
return DSA_SHA256;
}
String getJCAAlgorithm() {
+ return "SHA256withDSAinP1363Format";
+ }
+ String getJCAFallbackAlgorithm() {
return "SHA256withDSA";
}
Type getAlgorithmType() {
@@ -359,7 +548,7 @@
}
}
- static final class SHA1withECDSA extends DOMSignatureMethod {
+ static final class SHA1withECDSA extends AbstractECDSASignatureMethod {
SHA1withECDSA(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
@@ -371,6 +560,9 @@
return ECDSA_SHA1;
}
String getJCAAlgorithm() {
+ return "SHA1withECDSAinP1363Format";
+ }
+ String getJCAFallbackAlgorithm() {
return "SHA1withECDSA";
}
Type getAlgorithmType() {
@@ -378,7 +570,7 @@
}
}
- static final class SHA256withECDSA extends DOMSignatureMethod {
+ static final class SHA256withECDSA extends AbstractECDSASignatureMethod {
SHA256withECDSA(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
@@ -390,6 +582,9 @@
return ECDSA_SHA256;
}
String getJCAAlgorithm() {
+ return "SHA256withECDSAinP1363Format";
+ }
+ String getJCAFallbackAlgorithm() {
return "SHA256withECDSA";
}
Type getAlgorithmType() {
@@ -397,7 +592,7 @@
}
}
- static final class SHA384withECDSA extends DOMSignatureMethod {
+ static final class SHA384withECDSA extends AbstractECDSASignatureMethod {
SHA384withECDSA(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
@@ -409,6 +604,9 @@
return ECDSA_SHA384;
}
String getJCAAlgorithm() {
+ return "SHA384withECDSAinP1363Format";
+ }
+ String getJCAFallbackAlgorithm() {
return "SHA384withECDSA";
}
Type getAlgorithmType() {
@@ -416,7 +614,7 @@
}
}
- static final class SHA512withECDSA extends DOMSignatureMethod {
+ static final class SHA512withECDSA extends AbstractECDSASignatureMethod {
SHA512withECDSA(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
super(params);
@@ -428,6 +626,9 @@
return ECDSA_SHA512;
}
String getJCAAlgorithm() {
+ return "SHA512withECDSAinP1363Format";
+ }
+ String getJCAFallbackAlgorithm() {
return "SHA512withECDSA";
}
Type getAlgorithmType() {
--- a/jdk/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java Tue Feb 17 09:18:27 2015 -0800
+++ b/jdk/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java Tue Feb 17 10:48:24 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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
@@ -45,6 +45,12 @@
* . "SHA256withECDSA"
* . "SHA384withECDSA"
* . "SHA512withECDSA"
+ * . "NONEwithECDSAinP1363Format"
+ * . "SHA1withECDSAinP1363Format"
+ * . "SHA224withECDSAinP1363Format"
+ * . "SHA256withECDSAinP1363Format"
+ * . "SHA384withECDSAinP1363Format"
+ * . "SHA512withECDSAinP1363Format"
*
* @since 1.7
*/
@@ -65,29 +71,56 @@
// public key, if initialized for verifying
private ECPublicKey publicKey;
+ // The format. true for the IEEE P1363 format. false (default) for ASN.1
+ private final boolean p1363Format;
+
/**
- * Constructs a new ECDSASignature. Used by Raw subclass.
+ * Constructs a new ECDSASignature.
*
* @exception ProviderException if the native ECC library is unavailable.
*/
ECDSASignature() {
- messageDigest = null;
+ this(false);
+ }
+
+ /**
+ * Constructs a new ECDSASignature that will use the specified
+ * signature format. {@code p1363Format} should be {@code true} to
+ * use the IEEE P1363 format. If {@code p1363Format} is {@code false},
+ * the DER-encoded ASN.1 format will be used. This constructor is
+ * used by the RawECDSA subclasses.
+ */
+ ECDSASignature(boolean p1363Format) {
+ this.messageDigest = null;
+ this.p1363Format = p1363Format;
}
/**
* Constructs a new ECDSASignature. Used by subclasses.
*/
ECDSASignature(String digestName) {
+ this(digestName, false);
+ }
+
+ /**
+ * Constructs a new ECDSASignature that will use the specified
+ * digest and signature format. {@code p1363Format} should be
+ * {@code true} to use the IEEE P1363 format. If {@code p1363Format}
+ * is {@code false}, the DER-encoded ASN.1 format will be used. This
+ * constructor is used by subclasses.
+ */
+ ECDSASignature(String digestName, boolean p1363Format) {
try {
messageDigest = MessageDigest.getInstance(digestName);
} catch (NoSuchAlgorithmException e) {
throw new ProviderException(e);
}
- needsReset = false;
+ this.needsReset = false;
+ this.p1363Format = p1363Format;
}
- // Nested class for NONEwithECDSA signatures
- public static final class Raw extends ECDSASignature {
+ // Class for Raw ECDSA signatures.
+ static class RawECDSA extends ECDSASignature {
// the longest supported digest is 512 bits (SHA-512)
private static final int RAW_ECDSA_MAX = 64;
@@ -95,7 +128,8 @@
private final byte[] precomputedDigest;
private int offset = 0;
- public Raw() {
+ RawECDSA(boolean p1363Format) {
+ super(p1363Format);
precomputedDigest = new byte[RAW_ECDSA_MAX];
}
@@ -156,6 +190,20 @@
}
}
+ // Nested class for NONEwithECDSA signatures
+ public static final class Raw extends RawECDSA {
+ public Raw() {
+ super(false);
+ }
+ }
+
+ // Nested class for NONEwithECDSAinP1363Format signatures
+ public static final class RawinP1363Format extends RawECDSA {
+ public RawinP1363Format() {
+ super(true);
+ }
+ }
+
// Nested class for SHA1withECDSA signatures
public static final class SHA1 extends ECDSASignature {
public SHA1() {
@@ -163,6 +211,13 @@
}
}
+ // Nested class for SHA1withECDSAinP1363Format signatures
+ public static final class SHA1inP1363Format extends ECDSASignature {
+ public SHA1inP1363Format() {
+ super("SHA1", true);
+ }
+ }
+
// Nested class for SHA224withECDSA signatures
public static final class SHA224 extends ECDSASignature {
public SHA224() {
@@ -170,6 +225,13 @@
}
}
+ // Nested class for SHA224withECDSAinP1363Format signatures
+ public static final class SHA224inP1363Format extends ECDSASignature {
+ public SHA224inP1363Format() {
+ super("SHA-224", true);
+ }
+ }
+
// Nested class for SHA256withECDSA signatures
public static final class SHA256 extends ECDSASignature {
public SHA256() {
@@ -177,6 +239,13 @@
}
}
+ // Nested class for SHA256withECDSAinP1363Format signatures
+ public static final class SHA256inP1363Format extends ECDSASignature {
+ public SHA256inP1363Format() {
+ super("SHA-256", true);
+ }
+ }
+
// Nested class for SHA384withECDSA signatures
public static final class SHA384 extends ECDSASignature {
public SHA384() {
@@ -184,6 +253,13 @@
}
}
+ // Nested class for SHA384withECDSAinP1363Format signatures
+ public static final class SHA384inP1363Format extends ECDSASignature {
+ public SHA384inP1363Format() {
+ super("SHA-384", true);
+ }
+ }
+
// Nested class for SHA512withECDSA signatures
public static final class SHA512 extends ECDSASignature {
public SHA512() {
@@ -191,6 +267,13 @@
}
}
+ // Nested class for SHA512withECDSAinP1363Format signatures
+ public static final class SHA512inP1363Format extends ECDSASignature {
+ public SHA512inP1363Format() {
+ super("SHA-512", true);
+ }
+ }
+
// initialize for verification. See JCA doc
@Override
protected void engineInitVerify(PublicKey publicKey)
@@ -286,14 +369,18 @@
}
random.nextBytes(seed);
+ byte[] sig;
try {
-
- return encodeSignature(
- signDigest(getDigestValue(), s, encodedParams, seed));
-
+ sig = signDigest(getDigestValue(), s, encodedParams, seed);
} catch (GeneralSecurityException e) {
throw new SignatureException("Could not sign data", e);
}
+
+ if (p1363Format) {
+ return sig;
+ } else {
+ return encodeSignature(sig);
+ }
}
// verify the data and return the result. See JCA doc
@@ -311,11 +398,15 @@
w = ECUtil.encodePoint(publicKey.getW(), params.getCurve());
}
- try {
+ byte[] sig;
+ if (p1363Format) {
+ sig = signature;
+ } else {
+ sig = decodeSignature(signature);
+ }
- return verifySignedDigest(
- decodeSignature(signature), getDigestValue(), w, encodedParams);
-
+ try {
+ return verifySignedDigest(sig, getDigestValue(), w, encodedParams);
} catch (GeneralSecurityException e) {
throw new SignatureException("Could not verify signature", e);
}
--- a/jdk/src/jdk.crypto.ec/share/classes/sun/security/ec/SunECEntries.java Tue Feb 17 09:18:27 2015 -0800
+++ b/jdk/src/jdk.crypto.ec/share/classes/sun/security/ec/SunECEntries.java Tue Feb 17 10:48:24 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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
@@ -131,6 +131,19 @@
map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.4", "SHA512withECDSA");
map.put("Alg.Alias.Signature.1.2.840.10045.4.3.4", "SHA512withECDSA");
+ map.put("Signature.NONEwithECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$RawinP1363Format");
+ map.put("Signature.SHA1withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA1inP1363Format");
+ map.put("Signature.SHA224withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA224inP1363Format");
+ map.put("Signature.SHA256withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA256inP1363Format");
+ map.put("Signature.SHA384withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA384inP1363Format");
+ map.put("Signature.SHA512withECDSAinP1363Format",
+ "sun.security.ec.ECDSASignature$SHA512inP1363Format");
+
String ecKeyClasses = "java.security.interfaces.ECPublicKey" +
"|java.security.interfaces.ECPrivateKey";
map.put("Signature.NONEwithECDSA SupportedKeyClasses", ecKeyClasses);
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Signature.java Tue Feb 17 09:18:27 2015 -0800
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Signature.java Tue Feb 17 10:48:24 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -50,6 +50,8 @@
* . DSA
* . NONEwithDSA (RawDSA)
* . SHA1withDSA
+ * . NONEwithDSAinP1363Format (RawDSAinP1363Format)
+ * . SHA1withDSAinP1363Format
* . RSA:
* . MD2withRSA
* . MD5withRSA
@@ -65,6 +67,12 @@
* . SHA256withECDSA
* . SHA384withECDSA
* . SHA512withECDSA
+ * . NONEwithECDSAinP1363Format
+ * . SHA1withECDSAinP1363Format
+ * . SHA224withECDSAinP1363Format
+ * . SHA256withECDSAinP1363Format
+ * . SHA384withECDSAinP1363Format
+ * . SHA512withECDSAinP1363Format
*
* Note that the underlying PKCS#11 token may support complete signature
* algorithm (e.g. CKM_DSA_SHA1, CKM_MD5_RSA_PKCS), or it may just
@@ -117,6 +125,12 @@
// total number of bytes processed in current operation
private int bytesProcessed;
+ // The format, to be used for DSA and ECDSA signatures.
+ // If true, the IEEE P1363 format will be used, the concatenation of
+ // r and s. If false (default), the signature will be formatted as a
+ // DER-encoded ASN.1 sequence of r and s.
+ private boolean p1363Format = false;
+
// constant for signing mode
private final static int M_SIGN = 1;
// constant for verification mode
@@ -166,10 +180,12 @@
break;
case (int)CKM_DSA:
keyAlgorithm = "DSA";
- if (algorithm.equals("DSA")) {
+ if (algorithm.equals("DSA") ||
+ algorithm.equals("DSAinP1363Format")) {
type = T_DIGEST;
md = MessageDigest.getInstance("SHA-1");
- } else if (algorithm.equals("RawDSA")) {
+ } else if (algorithm.equals("RawDSA") ||
+ algorithm.equals("RawDSAinP1363Format")) {
type = T_RAW;
buffer = new byte[20];
} else {
@@ -178,20 +194,26 @@
break;
case (int)CKM_ECDSA:
keyAlgorithm = "EC";
- if (algorithm.equals("NONEwithECDSA")) {
+ if (algorithm.equals("NONEwithECDSA") ||
+ algorithm.equals("NONEwithECDSAinP1363Format")) {
type = T_RAW;
buffer = new byte[RAW_ECDSA_MAX];
} else {
String digestAlg;
- if (algorithm.equals("SHA1withECDSA")) {
+ if (algorithm.equals("SHA1withECDSA") ||
+ algorithm.equals("SHA1withECDSAinP1363Format")) {
digestAlg = "SHA-1";
- } else if (algorithm.equals("SHA224withECDSA")) {
+ } else if (algorithm.equals("SHA224withECDSA") ||
+ algorithm.equals("SHA224withECDSAinP1363Format")) {
digestAlg = "SHA-224";
- } else if (algorithm.equals("SHA256withECDSA")) {
+ } else if (algorithm.equals("SHA256withECDSA") ||
+ algorithm.equals("SHA256withECDSAinP1363Format")) {
digestAlg = "SHA-256";
- } else if (algorithm.equals("SHA384withECDSA")) {
+ } else if (algorithm.equals("SHA384withECDSA") ||
+ algorithm.equals("SHA384withECDSAinP1363Format")) {
digestAlg = "SHA-384";
- } else if (algorithm.equals("SHA512withECDSA")) {
+ } else if (algorithm.equals("SHA512withECDSA") ||
+ algorithm.equals("SHA512withECDSAinP1363Format")) {
digestAlg = "SHA-512";
} else {
throw new ProviderException(algorithm);
@@ -235,6 +257,9 @@
this.buffer = buffer;
this.digestOID = digestOID;
this.md = md;
+ if (algorithm.endsWith("inP1363Format")) {
+ this.p1363Format = true;
+ }
}
private void ensureInitialized() {
@@ -582,10 +607,14 @@
signature = token.p11.C_Sign(session.id(), data);
}
}
- if (keyAlgorithm.equals("RSA") == false) {
- return dsaToASN1(signature);
+ if (keyAlgorithm.equals("RSA")) {
+ return signature;
} else {
- return signature;
+ if (p1363Format) {
+ return signature;
+ } else {
+ return dsaToASN1(signature);
+ }
}
} catch (PKCS11Exception e) {
throw new ProviderException(e);
@@ -599,10 +628,12 @@
protected boolean engineVerify(byte[] signature) throws SignatureException {
ensureInitialized();
try {
- if (keyAlgorithm.equals("DSA")) {
- signature = asn1ToDSA(signature);
- } else if (keyAlgorithm.equals("EC")) {
- signature = asn1ToECDSA(signature);
+ if (!p1363Format) {
+ if (keyAlgorithm.equals("DSA")) {
+ signature = asn1ToDSA(signature);
+ } else if (keyAlgorithm.equals("EC")) {
+ signature = asn1ToECDSA(signature);
+ }
}
if (type == T_UPDATE) {
token.p11.C_VerifyFinal(session.id(), signature);
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java Tue Feb 17 09:18:27 2015 -0800
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java Tue Feb 17 10:48:24 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -680,6 +680,12 @@
s("SHA1withDSA", "1.3.14.3.2.13", "1.3.14.3.2.27",
"1.2.840.10040.4.3", "OID.1.2.840.10040.4.3"),
m(CKM_DSA_SHA1, CKM_DSA));
+ d(SIG, "RawDSAinP1363Format", P11Signature,
+ s("NONEwithDSAinP1363Format"),
+ m(CKM_DSA));
+ d(SIG, "DSAinP1363Format", P11Signature,
+ s("SHA1withDSAinP1363Format"),
+ m(CKM_DSA_SHA1, CKM_DSA));
d(SIG, "NONEwithECDSA", P11Signature,
m(CKM_ECDSA));
d(SIG, "SHA1withECDSA", P11Signature,
@@ -697,6 +703,18 @@
d(SIG, "SHA512withECDSA", P11Signature,
s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"),
m(CKM_ECDSA));
+ d(SIG, "NONEwithECDSAinP1363Format", P11Signature,
+ m(CKM_ECDSA));
+ d(SIG, "SHA1withECDSAinP1363Format", P11Signature,
+ m(CKM_ECDSA_SHA1, CKM_ECDSA));
+ d(SIG, "SHA224withECDSAinP1363Format", P11Signature,
+ m(CKM_ECDSA));
+ d(SIG, "SHA256withECDSAinP1363Format", P11Signature,
+ m(CKM_ECDSA));
+ d(SIG, "SHA384withECDSAinP1363Format", P11Signature,
+ m(CKM_ECDSA));
+ d(SIG, "SHA512withECDSAinP1363Format", P11Signature,
+ m(CKM_ECDSA));
d(SIG, "MD2withRSA", P11Signature,
s("1.2.840.113549.1.1.2", "OID.1.2.840.113549.1.1.2"),
m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
@@ -1061,7 +1079,7 @@
}
// EC
if (((type == KA) && algorithm.equals("ECDH"))
- || ((type == SIG) && algorithm.endsWith("ECDSA"))) {
+ || ((type == SIG) && algorithm.contains("ECDSA"))) {
if (keyAlgorithm.equals("EC") == false) {
return false;
}
@@ -1070,7 +1088,8 @@
|| (key instanceof ECPublicKey);
}
// DSA signatures
- if ((type == SIG) && algorithm.endsWith("DSA")) {
+ if ((type == SIG) && algorithm.contains("DSA") &&
+ !algorithm.contains("ECDSA")) {
if (keyAlgorithm.equals("DSA") == false) {
return false;
}
--- a/jdk/test/sun/security/pkcs11/ec/TestECDSA.java Tue Feb 17 09:18:27 2015 -0800
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDSA.java Tue Feb 17 10:48:24 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015, 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
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 6405536
+ * @bug 6405536 8042967
* @summary basic test of SHA1withECDSA and NONEwithECDSA signing/verifying
* @author Andreas Sterbenz
* @library ..
@@ -176,17 +176,28 @@
verify(provider, "NONEwithECDSA", publicKey, data1SHA, sig, true);
verify(provider, "NONEwithECDSA", publicKey, data2SHA, sig, false);
- testSigning(provider, privateKey, publicKey);
+ System.out.println("Testing with default signature format: ASN.1");
+ testSigning(provider, privateKey, publicKey, false);
+
+ System.out.println("Testing with IEEE P1363 signature format");
+ testSigning(provider, privateKey, publicKey, true);
}
- private void testSigning(Provider provider, PrivateKey privateKey,
- PublicKey publicKey) throws Exception {
+ private void testSigning(Provider provider,
+ PrivateKey privateKey,
+ PublicKey publicKey,
+ boolean p1363Format) throws Exception {
byte[] data = new byte[2048];
new Random().nextBytes(data);
// sign random data using SHA1withECDSA and verify using
// SHA1withECDSA and NONEwithECDSA
- Signature s = Signature.getInstance("SHA1withECDSA", provider);
+ Signature s;
+ if (p1363Format) {
+ s = Signature.getInstance("SHA1withECDSAinP1363Format", provider);
+ } else {
+ s = Signature.getInstance("SHA1withECDSA", provider);
+ }
s.initSign(privateKey);
s.update(data);
byte[] s1 = s.sign();
@@ -197,7 +208,11 @@
throw new Exception("Sign/verify 1 failed");
}
- s = Signature.getInstance("NONEwithECDSA", provider);
+ if (p1363Format) {
+ s = Signature.getInstance("NONEwithECDSAinP1363Format", provider);
+ } else {
+ s = Signature.getInstance("NONEwithECDSA", provider);
+ }
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] digest = md.digest(data);
s.initVerify(publicKey);
@@ -218,7 +233,11 @@
throw new Exception("Sign/verify 3 failed");
}
- s = Signature.getInstance("SHA1withECDSA", provider);
+ if (p1363Format) {
+ s = Signature.getInstance("SHA1withECDSAinP1363Format", provider);
+ } else {
+ s = Signature.getInstance("SHA1withECDSA", provider);
+ }
s.initVerify(publicKey);
s.update(data);
if (!s.verify(s2)) {
--- a/jdk/test/sun/security/provider/DSA/TestDSA2.java Tue Feb 17 09:18:27 2015 -0800
+++ b/jdk/test/sun/security/provider/DSA/TestDSA2.java Tue Feb 17 10:48:24 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -22,9 +22,10 @@
*/
/*
* @test
- * @bug 7044060
+ * @bug 7044060 8042967
* @run main/othervm/timeout=250 TestDSA2
- * @summary verify that DSA signature works using SHA and SHA-224 and SHA-256 digests.
+ * @summary verify that DSA signature works using SHA and SHA-224 and
+ * SHA-256 digests.
*/
@@ -40,7 +41,14 @@
private static final String PROV = "SUN";
private static final String[] SIG_ALGOS = {
- "SHA1withDSA", "SHA224withDSA", "SHA256withDSA"
+ "NONEwithDSA",
+ "SHA1withDSA",
+ "SHA224withDSA",
+ "SHA256withDSA",
+ "NONEwithDSAinP1363Format",
+ "SHA1withDSAinP1363Format",
+ "SHA224withDSAinP1363Format",
+ "SHA256withDSAinP1363Format"
};
private static final int[] KEYSIZES = {
@@ -48,15 +56,20 @@
};
public static void main(String[] args) throws Exception {
- boolean[] expectedToPass = { true, true, true };
+ boolean[] expectedToPass = { true, true, true, true,
+ true, true, true, true };
test(1024, expectedToPass);
- boolean[] expectedToPass2 = { true, true, true };
+ boolean[] expectedToPass2 = { true, true, true, true,
+ true, true, true, true };
test(2048, expectedToPass2);
}
private static void test(int keySize, boolean[] testStatus)
- throws Exception {
- byte[] data = "1234567890".getBytes();
+ throws Exception {
+ // Raw DSA requires the data to be exactly 20 bytes long. Use a
+ // 20-byte array for these tests so that the NONEwithDSA* algorithms
+ // don't complain.
+ byte[] data = "12345678901234567890".getBytes();
System.out.println("Test against key size: " + keySize);
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", PROV);