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