|
|
c89ed9 |
# HG changeset patch
|
|
|
c89ed9 |
# User David Stutzman<david.konrad.stutzman@us.army.mil>
|
|
|
c89ed9 |
# Date 1515711524 28800
|
|
|
c89ed9 |
# Thu Jan 11 14:58:44 2018 -0800
|
|
|
c89ed9 |
# Node ID 9e2db7eee6652330723d935c2b900b9b09b1ab9d
|
|
|
c89ed9 |
# Parent ca2c2fcfaf207f87c3c69e493f2b30fd0a088e95
|
|
|
c89ed9 |
Bug 1409867 - additional fix from dstutzman: allow signatures to be created correctly.
|
|
|
c89ed9 |
|
|
|
c89ed9 |
cfu for dstutzman
|
|
|
c89ed9 |
|
|
|
c89ed9 |
diff --git a/org/mozilla/jss/pkix/cms/SignerInfo.java b/org/mozilla/jss/pkix/cms/SignerInfo.java
|
|
|
c89ed9 |
--- a/org/mozilla/jss/pkix/cms/SignerInfo.java
|
|
|
c89ed9 |
+++ b/org/mozilla/jss/pkix/cms/SignerInfo.java
|
|
|
c89ed9 |
@@ -9,14 +9,10 @@
|
|
|
c89ed9 |
import org.mozilla.jss.util.Assert;
|
|
|
c89ed9 |
import org.mozilla.jss.pkix.primitive.*;
|
|
|
c89ed9 |
import org.mozilla.jss.crypto.*;
|
|
|
c89ed9 |
-import java.util.Vector;
|
|
|
c89ed9 |
-import java.math.BigInteger;
|
|
|
c89ed9 |
-import java.io.ByteArrayInputStream;
|
|
|
c89ed9 |
import java.security.InvalidKeyException;
|
|
|
c89ed9 |
import java.security.SignatureException;
|
|
|
c89ed9 |
import java.security.NoSuchAlgorithmException;
|
|
|
c89ed9 |
import java.security.MessageDigest;
|
|
|
c89ed9 |
-import org.mozilla.jss.crypto.*;
|
|
|
c89ed9 |
import org.mozilla.jss.crypto.X509Certificate;
|
|
|
c89ed9 |
import org.mozilla.jss.pkix.cert.*;
|
|
|
c89ed9 |
import org.mozilla.jss.*;
|
|
|
c89ed9 |
@@ -73,14 +69,6 @@
|
|
|
c89ed9 |
}
|
|
|
c89ed9 |
|
|
|
c89ed9 |
/**
|
|
|
c89ed9 |
- * Low-level method to set the version.
|
|
|
c89ed9 |
- * It is not normally necessary to call this. Use it at your own risk.
|
|
|
c89ed9 |
- public void setVersion(INTEGER version) {
|
|
|
c89ed9 |
- this.version = version;
|
|
|
c89ed9 |
- }
|
|
|
c89ed9 |
- */
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- /**
|
|
|
c89ed9 |
* Retrieves the SignerIdentifier.
|
|
|
c89ed9 |
*/
|
|
|
c89ed9 |
public SignerIdentifier getSignerIdentifier() {
|
|
|
c89ed9 |
@@ -88,14 +76,6 @@
|
|
|
c89ed9 |
}
|
|
|
c89ed9 |
|
|
|
c89ed9 |
/**
|
|
|
c89ed9 |
- * Low-level method to set the signerIdentifier.
|
|
|
c89ed9 |
- * It is not normally necessary to call this. Use it at your own risk.
|
|
|
c89ed9 |
- public void setSignerIdentifier( SignerIdentifier iasn ) {
|
|
|
c89ed9 |
- this.signerIdentifier = iasn;
|
|
|
c89ed9 |
- }
|
|
|
c89ed9 |
- */
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- /**
|
|
|
c89ed9 |
* Retrieves the DigestAlgorithm used in this SignerInfo.
|
|
|
c89ed9 |
*
|
|
|
c89ed9 |
* @exception NoSuchAlgorithmException If the algorithm is not
|
|
|
c89ed9 |
@@ -116,14 +96,6 @@
|
|
|
c89ed9 |
}
|
|
|
c89ed9 |
|
|
|
c89ed9 |
/**
|
|
|
c89ed9 |
- * Low-level method to set the digest AlgorithmIdentifier.
|
|
|
c89ed9 |
- * It is not normally necessary to call this. Use it at your own risk.
|
|
|
c89ed9 |
- public void setDigestAlgorithmIdentifier(AlgorithmIdentifier algid) {
|
|
|
c89ed9 |
- this.digestAlgorithm = algid;
|
|
|
c89ed9 |
- }
|
|
|
c89ed9 |
- */
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- /**
|
|
|
c89ed9 |
* Retrieves the signed attributes, if they exist.
|
|
|
c89ed9 |
*
|
|
|
c89ed9 |
*/
|
|
|
c89ed9 |
@@ -139,14 +111,6 @@
|
|
|
c89ed9 |
}
|
|
|
c89ed9 |
|
|
|
c89ed9 |
/**
|
|
|
c89ed9 |
- * Low-level method to set the signedAttributes field.
|
|
|
c89ed9 |
- * It is not normally necessary to call this. Use it at your own risk.
|
|
|
c89ed9 |
- public void setSignedAttributes(SET authAttrib) {
|
|
|
c89ed9 |
- this.signedAttributes = authAttrib;
|
|
|
c89ed9 |
- }
|
|
|
c89ed9 |
- */
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- /**
|
|
|
c89ed9 |
* Returns the raw signature (digest encryption) algorithm used in this
|
|
|
c89ed9 |
* SignerInfo.
|
|
|
c89ed9 |
*
|
|
|
c89ed9 |
@@ -168,15 +132,6 @@
|
|
|
c89ed9 |
}
|
|
|
c89ed9 |
|
|
|
c89ed9 |
/**
|
|
|
c89ed9 |
- * Low-level method to set the digestEncryptionAlgorithm field.
|
|
|
c89ed9 |
- * It is not normally necessary to call this. Use it at your own risk.
|
|
|
c89ed9 |
- public void
|
|
|
c89ed9 |
- setDigestEncryptionAlgorithmIdentifier(AlgorithmIdentifier algid) {
|
|
|
c89ed9 |
- this.digestEncryptionAlgorithm= algid;
|
|
|
c89ed9 |
- }
|
|
|
c89ed9 |
- */
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- /**
|
|
|
c89ed9 |
* Retrieves the encrypted digest.
|
|
|
c89ed9 |
*/
|
|
|
c89ed9 |
public byte[] getEncryptedDigest() {
|
|
|
c89ed9 |
@@ -184,14 +139,6 @@
|
|
|
c89ed9 |
}
|
|
|
c89ed9 |
|
|
|
c89ed9 |
/**
|
|
|
c89ed9 |
- * Low-level method to set the encryptedDigest field.
|
|
|
c89ed9 |
- * It is not normally necessary to call this. Use it at your own risk.
|
|
|
c89ed9 |
- public void setEncryptedDigest(byte[] ed) {
|
|
|
c89ed9 |
- this.encryptedDigest = new OCTET_STRING(ed);
|
|
|
c89ed9 |
- }
|
|
|
c89ed9 |
- */
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- /**
|
|
|
c89ed9 |
* Retrieves the unsigned attributes, if they exist.
|
|
|
c89ed9 |
*
|
|
|
c89ed9 |
*/
|
|
|
c89ed9 |
@@ -206,14 +153,6 @@
|
|
|
c89ed9 |
return (unsignedAttributes!=null);
|
|
|
c89ed9 |
}
|
|
|
c89ed9 |
|
|
|
c89ed9 |
- /**
|
|
|
c89ed9 |
- * Low-level method to set the unsignedAttributes field.
|
|
|
c89ed9 |
- * It is not normally necessary to call this. Use it at your own risk.
|
|
|
c89ed9 |
- public void setUnsignedAttributes(SET unauthAttrib) {
|
|
|
c89ed9 |
- this.unsignedAttributes = unauthAttrib;
|
|
|
c89ed9 |
- }
|
|
|
c89ed9 |
- */
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
///////////////////////////////////////////////////////////////////////
|
|
|
c89ed9 |
///////////////////////////////////////////////////////////////////////
|
|
|
c89ed9 |
// Constructors
|
|
|
c89ed9 |
@@ -221,17 +160,6 @@
|
|
|
c89ed9 |
///////////////////////////////////////////////////////////////////////
|
|
|
c89ed9 |
|
|
|
c89ed9 |
/**
|
|
|
c89ed9 |
- * Low-level default constructor. All fields are initialized to null.
|
|
|
c89ed9 |
- * Before this SignerInfo can be processed or used in any way, all of
|
|
|
c89ed9 |
- * the fields except signedAttributes and
|
|
|
c89ed9 |
- * unsignedAttributes must be non-null.
|
|
|
c89ed9 |
- * It is not normally necessary to call this constructor.Use it at
|
|
|
c89ed9 |
- * your own risk.
|
|
|
c89ed9 |
- public SignerInfo() {
|
|
|
c89ed9 |
- }
|
|
|
c89ed9 |
- */
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- /**
|
|
|
c89ed9 |
* A constructor for creating a new SignerInfo from scratch.
|
|
|
c89ed9 |
*
|
|
|
c89ed9 |
* @param signerIdentifier The signerIdentifier of the
|
|
|
c89ed9 |
@@ -303,36 +231,32 @@
|
|
|
c89ed9 |
//////////////////////////////////////////////////
|
|
|
c89ed9 |
|
|
|
c89ed9 |
// compute the digest
|
|
|
c89ed9 |
- byte[] digest=null;
|
|
|
c89ed9 |
- DigestAlgorithm digestAlg = signingAlg.getDigestAlg();
|
|
|
c89ed9 |
- if( signedAttributes == null ) {
|
|
|
c89ed9 |
+ CryptoToken token = signingKey.getOwningToken();
|
|
|
c89ed9 |
+ Signature sig;
|
|
|
c89ed9 |
+ byte[] toBeSigned = null;
|
|
|
c89ed9 |
+ if (signedAttributes == null) {
|
|
|
c89ed9 |
// just use the message digest of the content
|
|
|
c89ed9 |
- digest = messageDigest;
|
|
|
c89ed9 |
+ if (signingAlg.getRawAlg() == SignatureAlgorithm.RSASignature) {
|
|
|
c89ed9 |
+ SEQUENCE digestInfo = createDigestInfo(messageDigest, false);
|
|
|
c89ed9 |
+ toBeSigned = ASN1Util.encode(digestInfo);
|
|
|
c89ed9 |
+ } else {
|
|
|
c89ed9 |
+ toBeSigned = messageDigest;
|
|
|
c89ed9 |
+ }
|
|
|
c89ed9 |
+ sig = token.getSignatureContext(signingAlg.getRawAlg()); //data is already digested
|
|
|
c89ed9 |
} else {
|
|
|
c89ed9 |
- // digest the contents octets of the signed attributes
|
|
|
c89ed9 |
- byte[] enc = ASN1Util.encode(signedAttributes);
|
|
|
c89ed9 |
- MessageDigest md =
|
|
|
c89ed9 |
- MessageDigest.getInstance(digestAlg.toString());
|
|
|
c89ed9 |
- digest = md.digest( enc );
|
|
|
c89ed9 |
- }
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- byte[] toBeSigned;
|
|
|
c89ed9 |
- if( signingAlg.getRawAlg() == SignatureAlgorithm.RSASignature ) {
|
|
|
c89ed9 |
- // put the digest in a DigestInfo
|
|
|
c89ed9 |
- SEQUENCE digestInfo = new SEQUENCE();
|
|
|
c89ed9 |
- AlgorithmIdentifier digestAlgId =
|
|
|
c89ed9 |
- new AlgorithmIdentifier( digestAlg.toOID(),null );
|
|
|
c89ed9 |
- digestInfo.addElement( digestAlgId );
|
|
|
c89ed9 |
- digestInfo.addElement( new OCTET_STRING( digest ) );
|
|
|
c89ed9 |
- toBeSigned = ASN1Util.encode(digestInfo);
|
|
|
c89ed9 |
- } else {
|
|
|
c89ed9 |
- toBeSigned = digest;
|
|
|
c89ed9 |
+ byte[] encoding = ASN1Util.encode(signedAttributes);
|
|
|
c89ed9 |
+ if (signingAlg.getRawAlg() == SignatureAlgorithm.RSASignature) {
|
|
|
c89ed9 |
+ // put the digest in a DigestInfo
|
|
|
c89ed9 |
+ SEQUENCE digestInfo = createDigestInfo(encoding, true);
|
|
|
c89ed9 |
+ toBeSigned = ASN1Util.encode(digestInfo);
|
|
|
c89ed9 |
+ sig = token.getSignatureContext(SignatureAlgorithm.RSASignature);
|
|
|
c89ed9 |
+ } else {
|
|
|
c89ed9 |
+ toBeSigned = encoding;
|
|
|
c89ed9 |
+ sig = token.getSignatureContext(signingAlg);
|
|
|
c89ed9 |
+ }
|
|
|
c89ed9 |
}
|
|
|
c89ed9 |
|
|
|
c89ed9 |
// encrypt the DER-encoded DigestInfo with the private key
|
|
|
c89ed9 |
- CryptoToken token = signingKey.getOwningToken();
|
|
|
c89ed9 |
- Signature sig;
|
|
|
c89ed9 |
- sig = token.getSignatureContext( signingAlg );
|
|
|
c89ed9 |
sig.initSign(signingKey);
|
|
|
c89ed9 |
sig.update(toBeSigned);
|
|
|
c89ed9 |
encryptedDigest = new OCTET_STRING(sig.sign());
|
|
|
c89ed9 |
@@ -494,21 +418,20 @@
|
|
|
c89ed9 |
digestEncryptionAlgorithm.getOID()
|
|
|
c89ed9 |
);
|
|
|
c89ed9 |
|
|
|
c89ed9 |
+ CryptoToken token = CryptoManager.getInstance()
|
|
|
c89ed9 |
+ .getInternalCryptoToken();
|
|
|
c89ed9 |
+ Signature sig;
|
|
|
c89ed9 |
byte[] toBeVerified;
|
|
|
c89ed9 |
- if( sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature ) {
|
|
|
c89ed9 |
+ if (sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature) {
|
|
|
c89ed9 |
// create DigestInfo structure
|
|
|
c89ed9 |
- SEQUENCE digestInfo = new SEQUENCE();
|
|
|
c89ed9 |
- digestInfo.addElement(
|
|
|
c89ed9 |
- new AlgorithmIdentifier(digestAlgorithm.getOID(), null) );
|
|
|
c89ed9 |
- digestInfo.addElement( new OCTET_STRING(messageDigest) );
|
|
|
c89ed9 |
+ SEQUENCE digestInfo = createDigestInfo(messageDigest, false);
|
|
|
c89ed9 |
toBeVerified = ASN1Util.encode(digestInfo);
|
|
|
c89ed9 |
+ sig = token.getSignatureContext(sigAlg.getRawAlg());
|
|
|
c89ed9 |
} else {
|
|
|
c89ed9 |
toBeVerified = messageDigest;
|
|
|
c89ed9 |
+ sig = token.getSignatureContext(sigAlg);
|
|
|
c89ed9 |
}
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- CryptoToken token = CryptoManager.getInstance()
|
|
|
c89ed9 |
- .getInternalCryptoToken();
|
|
|
c89ed9 |
- Signature sig = token.getSignatureContext(sigAlg);
|
|
|
c89ed9 |
+
|
|
|
c89ed9 |
sig.initVerify(pubkey);
|
|
|
c89ed9 |
sig.update(toBeVerified);
|
|
|
c89ed9 |
if( sig.verify(encryptedDigest.toByteArray()) ) {
|
|
|
c89ed9 |
@@ -671,31 +594,22 @@
|
|
|
c89ed9 |
// Now verify the signature.
|
|
|
c89ed9 |
CryptoToken token =
|
|
|
c89ed9 |
CryptoManager.getInstance().getInternalCryptoToken();
|
|
|
c89ed9 |
- Signature sig = token.getSignatureContext( sigAlg );
|
|
|
c89ed9 |
- sig.initVerify(pubkey);
|
|
|
c89ed9 |
+ Signature sig;
|
|
|
c89ed9 |
|
|
|
c89ed9 |
// verify the contents octets of the DER encoded signed attribs
|
|
|
c89ed9 |
- byte[] toBeDigested = ASN1Util.encode(signedAttributes);
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- MessageDigest md = MessageDigest.getInstance(
|
|
|
c89ed9 |
- DigestAlgorithm.fromOID(digestAlgorithm.getOID()).toString() );
|
|
|
c89ed9 |
- byte[] digest = md.digest(toBeDigested);
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
+ byte[] encoding = ASN1Util.encode(signedAttributes);
|
|
|
c89ed9 |
byte[] toBeVerified;
|
|
|
c89ed9 |
- if( sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature ) {
|
|
|
c89ed9 |
+ if (sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature) {
|
|
|
c89ed9 |
// create DigestInfo structure
|
|
|
c89ed9 |
- SEQUENCE digestInfo = new SEQUENCE();
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- AlgorithmIdentifier digestAlgId =
|
|
|
c89ed9 |
- new AlgorithmIdentifier( digestAlgorithm.getOID(),null );
|
|
|
c89ed9 |
- digestInfo.addElement( digestAlgId );
|
|
|
c89ed9 |
-
|
|
|
c89ed9 |
- digestInfo.addElement( new OCTET_STRING(digest) );
|
|
|
c89ed9 |
+ SEQUENCE digestInfo = createDigestInfo(encoding, true);
|
|
|
c89ed9 |
toBeVerified = ASN1Util.encode(digestInfo);
|
|
|
c89ed9 |
+ sig = token.getSignatureContext(SignatureAlgorithm.RSASignature);
|
|
|
c89ed9 |
} else {
|
|
|
c89ed9 |
- toBeVerified = digest;
|
|
|
c89ed9 |
+ toBeVerified = encoding;
|
|
|
c89ed9 |
+ sig = token.getSignatureContext(sigAlg);
|
|
|
c89ed9 |
}
|
|
|
c89ed9 |
|
|
|
c89ed9 |
+ sig.initVerify(pubkey);
|
|
|
c89ed9 |
sig.update( toBeVerified );
|
|
|
c89ed9 |
|
|
|
c89ed9 |
if( ! sig.verify(encryptedDigest.toByteArray()) ) {
|
|
|
c89ed9 |
@@ -708,6 +622,25 @@
|
|
|
c89ed9 |
// SUCCESSFULLY VERIFIED
|
|
|
c89ed9 |
|
|
|
c89ed9 |
}
|
|
|
c89ed9 |
+
|
|
|
c89ed9 |
+ private SEQUENCE createDigestInfo(byte[] data, boolean doDigest) throws NoSuchAlgorithmException {
|
|
|
c89ed9 |
+ if(data == null || data.length == 0){
|
|
|
c89ed9 |
+ throw new IllegalArgumentException("Data to digest must be supplied");
|
|
|
c89ed9 |
+ }
|
|
|
c89ed9 |
+ SEQUENCE digestInfo = new SEQUENCE();
|
|
|
c89ed9 |
+ digestInfo.addElement(this.digestAlgorithm);
|
|
|
c89ed9 |
+ byte[] digest;
|
|
|
c89ed9 |
+ if (doDigest) {
|
|
|
c89ed9 |
+ MessageDigest md = MessageDigest.getInstance(
|
|
|
c89ed9 |
+ DigestAlgorithm.fromOID(this.digestAlgorithm.getOID()).toString());
|
|
|
c89ed9 |
+ digest = md.digest(data);
|
|
|
c89ed9 |
+ } else {
|
|
|
c89ed9 |
+ digest = data;
|
|
|
c89ed9 |
+ }
|
|
|
c89ed9 |
+ digestInfo.addElement(new OCTET_STRING(digest));
|
|
|
c89ed9 |
+ return digestInfo;
|
|
|
c89ed9 |
+ }
|
|
|
c89ed9 |
+
|
|
|
c89ed9 |
|
|
|
c89ed9 |
/**
|
|
|
c89ed9 |
* Compares two non-null byte arrays. Returns true if they are identical,
|