8042967: Add variant of DSA Signature algorithms that do not ASN.1 encode the signature bytes

Reviewed-by: mullan
This commit is contained in:
Jason Uh 2015-02-17 10:48:24 -08:00
parent 2b1139db7c
commit f7f4ab9df6
10 changed files with 643 additions and 135 deletions

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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() {

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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)) {

View File

@ -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);