use of java.security.Signature in project android_frameworks_base by ResurrectionRemix.
the class ApkSignatureSchemeV2Verifier method verifySigner.
private static X509Certificate[] verifySigner(ByteBuffer signerBlock, Map<Integer, byte[]> contentDigests, CertificateFactory certFactory) throws SecurityException, IOException {
ByteBuffer signedData = getLengthPrefixedSlice(signerBlock);
ByteBuffer signatures = getLengthPrefixedSlice(signerBlock);
byte[] publicKeyBytes = readLengthPrefixedByteArray(signerBlock);
int signatureCount = 0;
int bestSigAlgorithm = -1;
byte[] bestSigAlgorithmSignatureBytes = null;
List<Integer> signaturesSigAlgorithms = new ArrayList<>();
while (signatures.hasRemaining()) {
signatureCount++;
try {
ByteBuffer signature = getLengthPrefixedSlice(signatures);
if (signature.remaining() < 8) {
throw new SecurityException("Signature record too short");
}
int sigAlgorithm = signature.getInt();
signaturesSigAlgorithms.add(sigAlgorithm);
if (!isSupportedSignatureAlgorithm(sigAlgorithm)) {
continue;
}
if ((bestSigAlgorithm == -1) || (compareSignatureAlgorithm(sigAlgorithm, bestSigAlgorithm) > 0)) {
bestSigAlgorithm = sigAlgorithm;
bestSigAlgorithmSignatureBytes = readLengthPrefixedByteArray(signature);
}
} catch (IOException | BufferUnderflowException e) {
throw new SecurityException("Failed to parse signature record #" + signatureCount, e);
}
}
if (bestSigAlgorithm == -1) {
if (signatureCount == 0) {
throw new SecurityException("No signatures found");
} else {
throw new SecurityException("No supported signatures found");
}
}
String keyAlgorithm = getSignatureAlgorithmJcaKeyAlgorithm(bestSigAlgorithm);
Pair<String, ? extends AlgorithmParameterSpec> signatureAlgorithmParams = getSignatureAlgorithmJcaSignatureAlgorithm(bestSigAlgorithm);
String jcaSignatureAlgorithm = signatureAlgorithmParams.first;
AlgorithmParameterSpec jcaSignatureAlgorithmParams = signatureAlgorithmParams.second;
boolean sigVerified;
try {
PublicKey publicKey = KeyFactory.getInstance(keyAlgorithm).generatePublic(new X509EncodedKeySpec(publicKeyBytes));
Signature sig = Signature.getInstance(jcaSignatureAlgorithm);
sig.initVerify(publicKey);
if (jcaSignatureAlgorithmParams != null) {
sig.setParameter(jcaSignatureAlgorithmParams);
}
sig.update(signedData);
sigVerified = sig.verify(bestSigAlgorithmSignatureBytes);
} catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException | InvalidAlgorithmParameterException | SignatureException e) {
throw new SecurityException("Failed to verify " + jcaSignatureAlgorithm + " signature", e);
}
if (!sigVerified) {
throw new SecurityException(jcaSignatureAlgorithm + " signature did not verify");
}
// Signature over signedData has verified.
byte[] contentDigest = null;
signedData.clear();
ByteBuffer digests = getLengthPrefixedSlice(signedData);
List<Integer> digestsSigAlgorithms = new ArrayList<>();
int digestCount = 0;
while (digests.hasRemaining()) {
digestCount++;
try {
ByteBuffer digest = getLengthPrefixedSlice(digests);
if (digest.remaining() < 8) {
throw new IOException("Record too short");
}
int sigAlgorithm = digest.getInt();
digestsSigAlgorithms.add(sigAlgorithm);
if (sigAlgorithm == bestSigAlgorithm) {
contentDigest = readLengthPrefixedByteArray(digest);
}
} catch (IOException | BufferUnderflowException e) {
throw new IOException("Failed to parse digest record #" + digestCount, e);
}
}
if (!signaturesSigAlgorithms.equals(digestsSigAlgorithms)) {
throw new SecurityException("Signature algorithms don't match between digests and signatures records");
}
int digestAlgorithm = getSignatureAlgorithmContentDigestAlgorithm(bestSigAlgorithm);
byte[] previousSignerDigest = contentDigests.put(digestAlgorithm, contentDigest);
if ((previousSignerDigest != null) && (!MessageDigest.isEqual(previousSignerDigest, contentDigest))) {
throw new SecurityException(getContentDigestAlgorithmJcaDigestAlgorithm(digestAlgorithm) + " contents digest does not match the digest specified by a preceding signer");
}
ByteBuffer certificates = getLengthPrefixedSlice(signedData);
List<X509Certificate> certs = new ArrayList<>();
int certificateCount = 0;
while (certificates.hasRemaining()) {
certificateCount++;
byte[] encodedCert = readLengthPrefixedByteArray(certificates);
X509Certificate certificate;
try {
certificate = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(encodedCert));
} catch (CertificateException e) {
throw new SecurityException("Failed to decode certificate #" + certificateCount, e);
}
certificate = new VerbatimX509Certificate(certificate, encodedCert);
certs.add(certificate);
}
if (certs.isEmpty()) {
throw new SecurityException("No certificates listed");
}
X509Certificate mainCertificate = certs.get(0);
byte[] certificatePublicKeyBytes = mainCertificate.getPublicKey().getEncoded();
if (!Arrays.equals(publicKeyBytes, certificatePublicKeyBytes)) {
throw new SecurityException("Public key mismatch between certificate and signature record");
}
return certs.toArray(new X509Certificate[certs.size()]);
}
use of java.security.Signature in project OpenAM by OpenRock.
the class SecureLogHelperJSSImpl method signMAC.
/**
* Signs the given MAC
* @param mac the mac to be signed
* @return signed MAC for given mac entry
* @throws Exception if it fails to sign the MAC
*/
public byte[] signMAC(byte[] mac) throws Exception {
try {
PrivateKey loggerPrivKey = null;
X509Certificate cert = null;
try {
cert = cryptoMgr.findCertByNickname(loggerKey);
} catch (Exception e) {
Debug.error("SecureLogHelper.signMAC() : " + " Exception : ", e);
}
try {
loggerPrivKey = cryptoMgr.findPrivKeyByCert(cert);
} catch (Exception e) {
Debug.error("SecureLogHelper.signMAC() : " + " Exception : ", e);
}
Signature loggerSign = Signature.getInstance(signingAlgorithm);
loggerSign.initSign(loggerPrivKey);
loggerSign.update(mac);
byte[] signedBytes = loggerSign.sign();
writeToSecretStore(signedBytes, logFileName, loggerPass, currentSignature);
return signedBytes;
} catch (Exception e) {
Debug.error("SecureLogHelper.signMAC() : " + " Exception : ", e);
throw new Exception(e.getMessage());
}
}
use of java.security.Signature in project OpenAM by OpenRock.
the class SecureLogHelperJSSImpl method verifySignature.
/**
* Verifies the given signature
* @param signedObject the signature to be verified
* @param mac mac entry for the signature
* @return true if signature for mac is valid
* @throws Exception if it fails to verify signature value for mac entry
*/
public boolean verifySignature(byte[] signedObject, byte[] mac) throws Exception {
try {
PublicKey loggerPubKey = null;
X509Certificate cert = cryptoMgr.findCertByNickname(loggerKey);
loggerPubKey = cert.getPublicKey();
Signature verifySign = Signature.getInstance(signingAlgorithm);
verifySign.initVerify(loggerPubKey);
verifySign.update(mac);
return verifySign.verify(signedObject);
} catch (Exception e) {
Debug.error("SecureLogHelper.verifySignature() : " + " Exception : ", e);
throw new Exception(e.getMessage());
}
}
use of java.security.Signature in project OpenAM by OpenRock.
the class SecureLogHelperJCEImpl method signMAC.
/**
* Signs the given MAC
* @param mac the mac to be signed
* @return signed MAC for given mac entry
* @throws Exception if it fails to sign the MAC
*/
public byte[] signMAC(byte[] mac) throws Exception {
try {
PrivateKey loggerPrivKey = null;
try {
loggerPrivKey = ksManager.getPrivateKey(loggerKey);
} catch (Exception e) {
Debug.error("SecureLogHelper.signMAC() : " + " Exception : ", e);
}
Signature loggerSign = Signature.getInstance(signingAlgorithm);
loggerSign.initSign(loggerPrivKey);
loggerSign.update(mac);
byte[] signedBytes = loggerSign.sign();
writeToSecretStore(signedBytes, logFileName, loggerPass, currentSignature);
return signedBytes;
} catch (Exception e) {
Debug.error("SecureLogHelper.signMAC() : " + " Exception : ", e);
throw new Exception(e.getMessage());
}
}
use of java.security.Signature in project OpenAM by OpenRock.
the class QuerySignatureUtil method verify.
/**
* Verifies the query string signature.
*
* @param queryString Signed query String.
* @param verificationCerts Verification certificates.
* @return boolean whether the verification is successful or not.
* @throws SAML2Exception if there is an error during verification.
*/
public static boolean verify(String queryString, Set<X509Certificate> verificationCerts) throws SAML2Exception {
String classMethod = "QuerySignatureUtil.verify: ";
if (queryString == null || queryString.length() == 0 || verificationCerts.isEmpty()) {
SAML2Utils.debug.error(classMethod + "Input query string or certificate is null");
throw new SAML2Exception(SAML2Utils.bundle.getString("nullInput"));
}
if (SAML2Utils.debug.messageEnabled()) {
SAML2Utils.debug.message(classMethod + "Query string to be verifed:\n" + queryString);
}
StringTokenizer st = new StringTokenizer(queryString, "&");
String token = null;
String samlReq = null;
String samlRes = null;
String relay = null;
String sigAlg = null;
String encSig = null;
while (st.hasMoreTokens()) {
token = st.nextToken();
if (token.startsWith(SAML2Constants.SAML_REQUEST)) {
samlReq = token;
} else if (token.startsWith(SAML2Constants.SAML_RESPONSE)) {
samlRes = token;
} else if (token.startsWith(SAML2Constants.RELAY_STATE)) {
relay = token;
} else if (token.startsWith(SAML2Constants.SIG_ALG)) {
sigAlg = token;
} else if (token.startsWith(SAML2Constants.SIGNATURE)) {
encSig = token;
}
}
if (sigAlg == null || sigAlg.equals("")) {
SAML2Utils.debug.error(classMethod + "Null SigAlg query parameter.");
throw new SAML2Exception(SAML2Utils.bundle.getString("nullSigAlg"));
}
if (encSig == null || encSig.equals("")) {
SAML2Utils.debug.error(classMethod + "Null Signature query parameter.");
throw new SAML2Exception(SAML2Utils.bundle.getString("nullSig"));
}
// The following manipulation is necessary because
// other implementations could send the query
// parameters out of order, i.e., not in the same
// order when signature is produced
String newQueryString = null;
if (samlReq != null) {
newQueryString = samlReq;
} else {
newQueryString = samlRes;
}
if (relay != null) {
newQueryString += "&" + relay;
}
newQueryString += "&" + sigAlg;
if (SAML2Utils.debug.messageEnabled()) {
SAML2Utils.debug.message(classMethod + "Query string to be verifed (re-arranged):\n" + newQueryString);
}
int sigAlgValueIndex = sigAlg.indexOf('=');
String sigAlgValue = sigAlg.substring(sigAlgValueIndex + 1);
if (sigAlgValue == null || sigAlgValue.equals("")) {
SAML2Utils.debug.error(classMethod + "Null SigAlg query parameter value.");
throw new SAML2Exception(SAML2Utils.bundle.getString("nullSigAlg"));
}
sigAlgValue = URLEncDec.decode(sigAlgValue);
if (SAML2Utils.debug.messageEnabled()) {
SAML2Utils.debug.message(classMethod + "SigAlg query parameter value: " + sigAlgValue);
}
int encSigValueIndex = encSig.indexOf('=');
String encSigValue = encSig.substring(encSigValueIndex + 1);
if (encSigValue == null || encSigValue.equals("")) {
SAML2Utils.debug.message(classMethod + "Null Signature query parameter value.");
throw new SAML2Exception(SAML2Utils.bundle.getString("nullSig"));
}
encSigValue = URLEncDec.decode(encSigValue);
if (SAML2Utils.debug.messageEnabled()) {
SAML2Utils.debug.message(classMethod + "Signature query parameter value:\n" + encSigValue);
}
// base-64 decode the signature value
byte[] signature = null;
Base64 decoder = new Base64();
signature = decoder.decode(encSigValue);
// get Signature instance based on algorithm
if (!SIGNATURE.equals(JCEMapper.getAlgorithmClassFromURI(sigAlgValue))) {
SAML2Utils.debug.error(classMethod + "Signature algorithm " + sigAlgValue + " is not supported.");
throw new SAML2Exception(SAML2Utils.bundle.getString("algNotSupported"));
}
Signature sig;
try {
sig = Signature.getInstance(JCEMapper.translateURItoJCEID(sigAlgValue));
} catch (NoSuchAlgorithmException nsae) {
throw new SAML2Exception(nsae);
}
return isValidSignature(sig, verificationCerts, newQueryString.getBytes(), signature);
}
Aggregations