use of java.security.SignatureException in project jdk8u_jdk by JetBrains.
the class SignerInfo method verify.
/* Returns null if verify fails, this signerInfo if
verify succeeds. */
SignerInfo verify(PKCS7 block, byte[] data) throws NoSuchAlgorithmException, SignatureException {
try {
ContentInfo content = block.getContentInfo();
if (data == null) {
data = content.getContentBytes();
}
ConstraintsParameters cparams = new ConstraintsParameters(timestamp);
String digestAlgname = getDigestAlgorithmId().getName();
byte[] dataSigned;
// digest and compare it with the digest of data
if (authenticatedAttributes == null) {
dataSigned = data;
} else {
// first, check content type
ObjectIdentifier contentType = (ObjectIdentifier) authenticatedAttributes.getAttributeValue(PKCS9Attribute.CONTENT_TYPE_OID);
if (contentType == null || !contentType.equals((Object) content.contentType))
// contentType does not match, bad SignerInfo
return null;
// now, check message digest
byte[] messageDigest = (byte[]) authenticatedAttributes.getAttributeValue(PKCS9Attribute.MESSAGE_DIGEST_OID);
if (// fail if there is no message digest
messageDigest == null)
return null;
// check that digest algorithm is not restricted
try {
JAR_DISABLED_CHECK.permits(digestAlgname, cparams);
} catch (CertPathValidatorException e) {
throw new SignatureException(e.getMessage(), e);
}
MessageDigest md = MessageDigest.getInstance(digestAlgname);
byte[] computedMessageDigest = md.digest(data);
if (messageDigest.length != computedMessageDigest.length)
return null;
for (int i = 0; i < messageDigest.length; i++) {
if (messageDigest[i] != computedMessageDigest[i])
return null;
}
// message digest attribute matched
// digest of original data
// the data actually signed is the DER encoding of
// the authenticated attributes (tagged with
// the "SET OF" tag, not 0xA0).
dataSigned = authenticatedAttributes.getDerEncoding();
}
// put together digest algorithm and encryption algorithm
// to form signing algorithm
String encryptionAlgname = getDigestEncryptionAlgorithmId().getName();
// Workaround: sometimes the encryptionAlgname is actually
// a signature name
String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname);
if (tmp != null)
encryptionAlgname = tmp;
String algname = AlgorithmId.makeSigAlg(digestAlgname, encryptionAlgname);
// check that jar signature algorithm is not restricted
try {
JAR_DISABLED_CHECK.permits(algname, cparams);
} catch (CertPathValidatorException e) {
throw new SignatureException(e.getMessage(), e);
}
X509Certificate cert = getCertificate(block);
if (cert == null) {
return null;
}
PublicKey key = cert.getPublicKey();
// check if the public key is restricted
if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
throw new SignatureException("Public key check failed. " + "Disabled key used: " + KeyUtil.getKeySize(key) + " bit " + key.getAlgorithm());
}
if (cert.hasUnsupportedCriticalExtension()) {
throw new SignatureException("Certificate has unsupported " + "critical extension(s)");
}
// Make sure that if the usage of the key in the certificate is
// restricted, it can be used for digital signatures.
// XXX We may want to check for additional extensions in the
// future.
boolean[] keyUsageBits = cert.getKeyUsage();
if (keyUsageBits != null) {
KeyUsageExtension keyUsage;
try {
// We don't care whether or not this extension was marked
// critical in the certificate.
// We're interested only in its value (i.e., the bits set)
// and treat the extension as critical.
keyUsage = new KeyUsageExtension(keyUsageBits);
} catch (IOException ioe) {
throw new SignatureException("Failed to parse keyUsage " + "extension");
}
boolean digSigAllowed = keyUsage.get(KeyUsageExtension.DIGITAL_SIGNATURE).booleanValue();
boolean nonRepuAllowed = keyUsage.get(KeyUsageExtension.NON_REPUDIATION).booleanValue();
if (!digSigAllowed && !nonRepuAllowed) {
throw new SignatureException("Key usage restricted: " + "cannot be used for " + "digital signatures");
}
}
Signature sig = Signature.getInstance(algname);
sig.initVerify(key);
sig.update(dataSigned);
if (sig.verify(encryptedDigest)) {
return this;
}
} catch (IOException e) {
throw new SignatureException("IO error verifying signature:\n" + e.getMessage());
} catch (InvalidKeyException e) {
throw new SignatureException("InvalidKey: " + e.getMessage());
}
return null;
}
use of java.security.SignatureException in project jdk8u_jdk by JetBrains.
the class SignerInfo method verifyTimestamp.
/*
* Check that the signature timestamp applies to this signature.
* Match the hash present in the signature timestamp token against the hash
* of this signature.
*/
private void verifyTimestamp(TimestampToken token) throws NoSuchAlgorithmException, SignatureException {
String digestAlgname = token.getHashAlgorithm().getName();
// check that algorithm is not restricted
if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, digestAlgname, null)) {
throw new SignatureException("Timestamp token digest check failed. " + "Disabled algorithm used: " + digestAlgname);
}
MessageDigest md = MessageDigest.getInstance(digestAlgname);
if (!Arrays.equals(token.getHashedMessage(), md.digest(encryptedDigest))) {
throw new SignatureException("Signature timestamp (#" + token.getSerialNumber() + ") generated on " + token.getDate() + " is inapplicable");
}
if (debug != null) {
debug.println();
debug.println("Detected signature timestamp (#" + token.getSerialNumber() + ") generated on " + token.getDate());
debug.println();
}
}
use of java.security.SignatureException in project jdk8u_jdk by JetBrains.
the class SignatureFileVerifier method verifyManifestHash.
/**
* See if the whole manifest was signed.
*/
private boolean verifyManifestHash(Manifest sf, ManifestDigester md, List<Object> manifestDigests) throws IOException, SignatureException {
Attributes mattr = sf.getMainAttributes();
boolean manifestSigned = false;
// If only weak algorithms are used.
boolean weakAlgs = true;
// If a "*-DIGEST-MANIFEST" entry is found.
boolean validEntry = false;
// go through all the attributes and process *-Digest-Manifest entries
for (Map.Entry<Object, Object> se : mattr.entrySet()) {
String key = se.getKey().toString();
if (key.toUpperCase(Locale.ENGLISH).endsWith("-DIGEST-MANIFEST")) {
// 16 is length of "-Digest-Manifest"
String algorithm = key.substring(0, key.length() - 16);
validEntry = true;
// Check if this algorithm is permitted, skip if false.
if (!permittedCheck(key, algorithm)) {
continue;
}
// A non-weak algorithm was used, any weak algorithms found do
// not need to be reported.
weakAlgs = false;
manifestDigests.add(key);
manifestDigests.add(se.getValue());
MessageDigest digest = getDigest(algorithm);
if (digest != null) {
byte[] computedHash = md.manifestDigest(digest);
byte[] expectedHash = Base64.getMimeDecoder().decode((String) se.getValue());
if (debug != null) {
debug.println("Signature File: Manifest digest " + algorithm);
debug.println(" sigfile " + toHex(expectedHash));
debug.println(" computed " + toHex(computedHash));
debug.println();
}
if (MessageDigest.isEqual(computedHash, expectedHash)) {
manifestSigned = true;
} else {
//XXX: we will continue and verify each section
}
}
}
}
if (debug != null) {
debug.println("PermittedAlgs mapping: ");
for (String key : permittedAlgs.keySet()) {
debug.println(key + " : " + permittedAlgs.get(key).toString());
}
}
// If there were only weak algorithms entries used, throw an exception.
if (validEntry && weakAlgs) {
throw new SignatureException("Manifest hash check failed " + "(DIGEST-MANIFEST). Disabled algorithm(s) used: " + getWeakAlgorithms("-DIGEST-MANIFEST"));
}
return manifestSigned;
}
use of java.security.SignatureException in project jdk8u_jdk by JetBrains.
the class SignatureFileVerifier method verifySection.
/**
* given the .SF digest header, and the data from the
* section in the manifest, see if the hashes match.
* if not, throw a SecurityException.
*
* @return true if all the -Digest headers verified
* @exception SecurityException if the hash was not equal
*/
private boolean verifySection(Attributes sfAttr, String name, ManifestDigester md) throws IOException, SignatureException {
boolean oneDigestVerified = false;
ManifestDigester.Entry mde = md.get(name, block.isOldStyle());
// If only weak algorithms are used.
boolean weakAlgs = true;
// If a "*-DIGEST" entry is found.
boolean validEntry = false;
if (mde == null) {
throw new SecurityException("no manifest section for signature file entry " + name);
}
if (sfAttr != null) {
// go through all the attributes and process *-Digest entries
for (Map.Entry<Object, Object> se : sfAttr.entrySet()) {
String key = se.getKey().toString();
if (key.toUpperCase(Locale.ENGLISH).endsWith("-DIGEST")) {
// 7 is length of "-Digest"
String algorithm = key.substring(0, key.length() - 7);
validEntry = true;
// Check if this algorithm is permitted, skip if false.
if (!permittedCheck(key, algorithm)) {
continue;
}
// A non-weak algorithm was used, any weak algorithms found do
// not need to be reported.
weakAlgs = false;
MessageDigest digest = getDigest(algorithm);
if (digest != null) {
boolean ok = false;
byte[] expected = Base64.getMimeDecoder().decode((String) se.getValue());
byte[] computed;
if (workaround) {
computed = mde.digestWorkaround(digest);
} else {
computed = mde.digest(digest);
}
if (debug != null) {
debug.println("Signature Block File: " + name + " digest=" + digest.getAlgorithm());
debug.println(" expected " + toHex(expected));
debug.println(" computed " + toHex(computed));
debug.println();
}
if (MessageDigest.isEqual(computed, expected)) {
oneDigestVerified = true;
ok = true;
} else {
// attempt to fallback to the workaround
if (!workaround) {
computed = mde.digestWorkaround(digest);
if (MessageDigest.isEqual(computed, expected)) {
if (debug != null) {
debug.println(" re-computed " + toHex(computed));
debug.println();
}
workaround = true;
oneDigestVerified = true;
ok = true;
}
}
}
if (!ok) {
throw new SecurityException("invalid " + digest.getAlgorithm() + " signature file digest for " + name);
}
}
}
}
}
if (debug != null) {
debug.println("PermittedAlgs mapping: ");
for (String key : permittedAlgs.keySet()) {
debug.println(key + " : " + permittedAlgs.get(key).toString());
}
}
// If there were only weak algorithms entries used, throw an exception.
if (validEntry && weakAlgs) {
throw new SignatureException("Manifest Main Attribute check " + "failed (DIGEST). Disabled algorithm(s) used: " + getWeakAlgorithms("DIGEST"));
}
return oneDigestVerified;
}
use of java.security.SignatureException in project jdk8u_jdk by JetBrains.
the class X509CRLImpl method verify.
/**
* Verifies that this CRL was signed using the
* private key that corresponds to the given public key,
* and that the signature verification was computed by
* the given provider.
*
* @param key the PublicKey used to carry out the verification.
* @param sigProvider the name of the signature provider.
*
* @exception NoSuchAlgorithmException on unsupported signature
* algorithms.
* @exception InvalidKeyException on incorrect key.
* @exception NoSuchProviderException on incorrect provider.
* @exception SignatureException on signature errors.
* @exception CRLException on encoding errors.
*/
public synchronized void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException {
if (sigProvider == null) {
sigProvider = "";
}
if ((verifiedPublicKey != null) && verifiedPublicKey.equals(key)) {
// this public key. Make sure providers match, too.
if (sigProvider.equals(verifiedProvider)) {
return;
}
}
if (signedCRL == null) {
throw new CRLException("Uninitialized CRL");
}
Signature sigVerf = null;
if (sigProvider.length() == 0) {
sigVerf = Signature.getInstance(sigAlgId.getName());
} else {
sigVerf = Signature.getInstance(sigAlgId.getName(), sigProvider);
}
sigVerf.initVerify(key);
if (tbsCertList == null) {
throw new CRLException("Uninitialized CRL");
}
sigVerf.update(tbsCertList, 0, tbsCertList.length);
if (!sigVerf.verify(signature)) {
throw new SignatureException("Signature does not match.");
}
verifiedPublicKey = key;
verifiedProvider = sigProvider;
}
Aggregations