mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-06 08:28:27 +00:00
8042967: Add variant of DSA Signature algorithms that do not ASN.1 encode the signature bytes
Reviewed-by: mullan
This commit is contained in:
parent
2b1139db7c
commit
f7f4ab9df6
@ -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.nio.ByteBuffer;
|
||||
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 @@ abstract class DSA extends SignatureSpi {
|
||||
/* 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 @@ abstract class DSA extends SignatureSpi {
|
||||
|
||||
|
||||
/**
|
||||
* 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 @@ abstract class DSA extends SignatureSpi {
|
||||
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();
|
||||
|
||||
return result.toByteArray();
|
||||
int size = presetQ.bitLength() / 8;
|
||||
byte[] outseq = new byte[size * 2];
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new SignatureException("error encoding signature");
|
||||
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--);
|
||||
|
||||
System.arraycopy(rBytes, rLength - i, outseq, size - i, i);
|
||||
System.arraycopy(sBytes, sLength - j, outseq, size * 2 - j, j);
|
||||
|
||||
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 @@ abstract class DSA extends SignatureSpi {
|
||||
/**
|
||||
* 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 @@ abstract class DSA extends SignatureSpi {
|
||||
|
||||
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
|
||||
@ -420,6 +477,15 @@ abstract class DSA extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@ -429,6 +495,15 @@ abstract class DSA extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ abstract class DSA extends SignatureSpi {
|
||||
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 @@ abstract class DSA extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard SHA1withDSA implementation.
|
||||
*/
|
||||
public static final class SHA1withDSA extends LegacyDSA {
|
||||
public SHA1withDSA() throws NoSuchAlgorithmException {
|
||||
super(MessageDigest.getInstance("SHA-1"));
|
||||
@ -643,13 +726,22 @@ abstract class DSA extends SignatureSpi {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ abstract class DSA extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 @@ final class SunEntries {
|
||||
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);
|
||||
|
||||
@ -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 @@ public class DisabledAlgorithmConstraints implements AlgorithmConstraints {
|
||||
// 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) {
|
||||
|
||||
@ -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 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
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 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
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 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
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 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA1withRSA extends DOMSignatureMethod {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA256withRSA extends DOMSignatureMethod {
|
||||
static final class SHA256withRSA extends AbstractRSASignatureMethod {
|
||||
SHA256withRSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
@ -283,7 +466,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA384withRSA extends DOMSignatureMethod {
|
||||
static final class SHA384withRSA extends AbstractRSASignatureMethod {
|
||||
SHA384withRSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
@ -302,7 +485,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA512withRSA extends DOMSignatureMethod {
|
||||
static final class SHA512withRSA extends AbstractRSASignatureMethod {
|
||||
SHA512withRSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
@ -321,7 +504,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA1withDSA extends DOMSignatureMethod {
|
||||
static final class SHA1withDSA extends AbstractDSASignatureMethod {
|
||||
SHA1withDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
@ -333,6 +516,9 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
return SignatureMethod.DSA_SHA1;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA1withDSAinP1363Format";
|
||||
}
|
||||
String getJCAFallbackAlgorithm() {
|
||||
return "SHA1withDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
@ -340,7 +526,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA256withDSA extends DOMSignatureMethod {
|
||||
static final class SHA256withDSA extends AbstractDSASignatureMethod {
|
||||
SHA256withDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
@ -352,6 +538,9 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
return DSA_SHA256;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA256withDSAinP1363Format";
|
||||
}
|
||||
String getJCAFallbackAlgorithm() {
|
||||
return "SHA256withDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
@ -359,7 +548,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA1withECDSA extends DOMSignatureMethod {
|
||||
static final class SHA1withECDSA extends AbstractECDSASignatureMethod {
|
||||
SHA1withECDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
@ -371,6 +560,9 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
return ECDSA_SHA1;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA1withECDSAinP1363Format";
|
||||
}
|
||||
String getJCAFallbackAlgorithm() {
|
||||
return "SHA1withECDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
@ -378,7 +570,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA256withECDSA extends DOMSignatureMethod {
|
||||
static final class SHA256withECDSA extends AbstractECDSASignatureMethod {
|
||||
SHA256withECDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
@ -390,6 +582,9 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
return ECDSA_SHA256;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA256withECDSAinP1363Format";
|
||||
}
|
||||
String getJCAFallbackAlgorithm() {
|
||||
return "SHA256withECDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
@ -397,7 +592,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA384withECDSA extends DOMSignatureMethod {
|
||||
static final class SHA384withECDSA extends AbstractECDSASignatureMethod {
|
||||
SHA384withECDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
@ -409,6 +604,9 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
return ECDSA_SHA384;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA384withECDSAinP1363Format";
|
||||
}
|
||||
String getJCAFallbackAlgorithm() {
|
||||
return "SHA384withECDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
@ -416,7 +614,7 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
}
|
||||
}
|
||||
|
||||
static final class SHA512withECDSA extends DOMSignatureMethod {
|
||||
static final class SHA512withECDSA extends AbstractECDSASignatureMethod {
|
||||
SHA512withECDSA(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(params);
|
||||
@ -428,6 +626,9 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
return ECDSA_SHA512;
|
||||
}
|
||||
String getJCAAlgorithm() {
|
||||
return "SHA512withECDSAinP1363Format";
|
||||
}
|
||||
String getJCAFallbackAlgorithm() {
|
||||
return "SHA512withECDSA";
|
||||
}
|
||||
Type getAlgorithmType() {
|
||||
|
||||
@ -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 @@ import sun.security.util.*;
|
||||
* . "SHA256withECDSA"
|
||||
* . "SHA384withECDSA"
|
||||
* . "SHA512withECDSA"
|
||||
* . "NONEwithECDSAinP1363Format"
|
||||
* . "SHA1withECDSAinP1363Format"
|
||||
* . "SHA224withECDSAinP1363Format"
|
||||
* . "SHA256withECDSAinP1363Format"
|
||||
* . "SHA384withECDSAinP1363Format"
|
||||
* . "SHA512withECDSAinP1363Format"
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
@ -65,29 +71,56 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
// 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 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
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 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
}
|
||||
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 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||
w = ECUtil.encodePoint(publicKey.getW(), params.getCurve());
|
||||
}
|
||||
|
||||
byte[] sig;
|
||||
if (p1363Format) {
|
||||
sig = signature;
|
||||
} else {
|
||||
sig = decodeSignature(signature);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
return verifySignedDigest(
|
||||
decodeSignature(signature), getDigestValue(), w, encodedParams);
|
||||
|
||||
return verifySignedDigest(sig, getDigestValue(), w, encodedParams);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new SignatureException("Could not verify signature", e);
|
||||
}
|
||||
|
||||
@ -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 @@ final class SunECEntries {
|
||||
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);
|
||||
|
||||
@ -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 @@ import sun.security.util.KeyUtil;
|
||||
* . DSA
|
||||
* . NONEwithDSA (RawDSA)
|
||||
* . SHA1withDSA
|
||||
* . NONEwithDSAinP1363Format (RawDSAinP1363Format)
|
||||
* . SHA1withDSAinP1363Format
|
||||
* . RSA:
|
||||
* . MD2withRSA
|
||||
* . MD5withRSA
|
||||
@ -65,6 +67,12 @@ import sun.security.util.KeyUtil;
|
||||
* . 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 @@ final class P11Signature extends SignatureSpi {
|
||||
// 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 @@ final class P11Signature extends SignatureSpi {
|
||||
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 @@ final class P11Signature extends SignatureSpi {
|
||||
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 @@ final class P11Signature extends SignatureSpi {
|
||||
this.buffer = buffer;
|
||||
this.digestOID = digestOID;
|
||||
this.md = md;
|
||||
if (algorithm.endsWith("inP1363Format")) {
|
||||
this.p1363Format = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureInitialized() {
|
||||
@ -582,10 +607,14 @@ final class P11Signature extends SignatureSpi {
|
||||
signature = token.p11.C_Sign(session.id(), data);
|
||||
}
|
||||
}
|
||||
if (keyAlgorithm.equals("RSA") == false) {
|
||||
return dsaToASN1(signature);
|
||||
} else {
|
||||
if (keyAlgorithm.equals("RSA")) {
|
||||
return signature;
|
||||
} else {
|
||||
if (p1363Format) {
|
||||
return signature;
|
||||
} else {
|
||||
return dsaToASN1(signature);
|
||||
}
|
||||
}
|
||||
} catch (PKCS11Exception e) {
|
||||
throw new ProviderException(e);
|
||||
@ -599,10 +628,12 @@ final class P11Signature extends SignatureSpi {
|
||||
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);
|
||||
|
||||
@ -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 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
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 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
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 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
}
|
||||
// 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 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
|| (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;
|
||||
}
|
||||
|
||||
@ -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 @@ public class TestECDSA extends PKCS11Test {
|
||||
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 @@ public class TestECDSA extends PKCS11Test {
|
||||
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 @@ public class TestECDSA extends PKCS11Test {
|
||||
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)) {
|
||||
|
||||
@ -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 @@ public class TestDSA2 {
|
||||
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 class TestDSA2 {
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user