use of org.bouncycastle.asn1.x509.Time in project documentproduction by qld-gov-au.
the class OcspHelper method verifyOcspResponse.
/**
* Verifies the status and the response itself (including nonce), but not the signature.
*
* @param ocspResponse to be verified
* @throws OCSPException
* @throws RevokedCertificateException
* @throws IOException if the default security provider can't be instantiated
*/
private void verifyOcspResponse(OCSPResp ocspResponse) throws OCSPException, RevokedCertificateException, IOException {
verifyRespStatus(ocspResponse);
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
if (basicResponse != null) {
ResponderID responderID = basicResponse.getResponderId().toASN1Primitive();
// https://tools.ietf.org/html/rfc6960#section-4.2.2.3
// The basic response type contains:
// (...)
// either the name of the responder or a hash of the responder's
// public key as the ResponderID
// (...)
// The responder MAY include certificates in the certs field of
// BasicOCSPResponse that help the OCSP client verify the responder's
// signature.
X500Name name = responderID.getName();
if (name != null) {
findResponderCertificateByName(basicResponse, name);
} else {
byte[] keyHash = responderID.getKeyHash();
if (keyHash != null) {
findResponderCertificateByKeyHash(basicResponse, keyHash);
} else {
throw new OCSPException("OCSP: basic response must provide name or key hash");
}
}
if (ocspResponderCertificate == null) {
throw new OCSPException("OCSP: certificate for responder " + name + " not found");
}
try {
SigUtils.checkResponderCertificateUsage(ocspResponderCertificate);
} catch (CertificateParsingException ex) {
// unlikely to happen because the certificate existed as an object
LOG.error(ex.getMessage(), ex);
}
checkOcspSignature(ocspResponderCertificate, basicResponse);
boolean nonceChecked = checkNonce(basicResponse);
SingleResp[] responses = basicResponse.getResponses();
if (responses.length != 1) {
throw new OCSPException("OCSP: Received " + responses.length + " responses instead of 1!");
}
SingleResp resp = responses[0];
Object status = resp.getCertStatus();
if (!nonceChecked) {
// https://tools.ietf.org/html/rfc5019
// fall back to validating the OCSPResponse based on time
checkOcspResponseFresh(resp);
}
if (status instanceof RevokedStatus) {
RevokedStatus revokedStatus = (RevokedStatus) status;
if (revokedStatus.getRevocationTime().compareTo(signDate) <= 0) {
throw new RevokedCertificateException("OCSP: Certificate is revoked since " + revokedStatus.getRevocationTime(), revokedStatus.getRevocationTime());
}
LOG.info("The certificate was revoked after signing by OCSP " + ocspUrl + " on " + revokedStatus.getRevocationTime());
} else if (status != CertificateStatus.GOOD) {
throw new OCSPException("OCSP: Status of Cert is unknown");
}
}
}
use of org.bouncycastle.asn1.x509.Time in project itext2 by albfernandez.
the class PdfPKCS7 method getEncodedPKCS7.
/**
* Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes
* in the signerInfo can also be set, OR a time-stamp-authority client
* may be provided.
* @param secondDigest the digest in the authenticatedAttributes
* @param signingTime the signing time in the authenticatedAttributes
* @param tsaClient TSAClient - null or an optional time stamp authority client
* @return byte[] the bytes for the PKCS7SignedData object
* @since 2.1.6
*/
public byte[] getEncodedPKCS7(byte[] secondDigest, Calendar signingTime, TSAClient tsaClient, byte[] ocsp) {
try {
if (externalDigest != null) {
digest = externalDigest;
if (RSAdata != null)
RSAdata = externalRSAdata;
} else if (externalRSAdata != null && RSAdata != null) {
RSAdata = externalRSAdata;
sig.update(RSAdata);
digest = sig.sign();
} else {
if (RSAdata != null) {
RSAdata = messageDigest.digest();
sig.update(RSAdata);
}
digest = sig.sign();
}
// Create the set of Hash algorithms
ASN1EncodableVector digestAlgorithms = new ASN1EncodableVector();
for (Iterator it = digestalgos.iterator(); it.hasNext(); ) {
ASN1EncodableVector algos = new ASN1EncodableVector();
algos.add(new ASN1ObjectIdentifier((String) it.next()));
algos.add(DERNull.INSTANCE);
digestAlgorithms.add(new DERSequence(algos));
}
// Create the contentInfo.
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(new ASN1ObjectIdentifier(ID_PKCS7_DATA));
if (RSAdata != null)
v.add(new DERTaggedObject(0, new DEROctetString(RSAdata)));
DERSequence contentinfo = new DERSequence(v);
// Get all the certificates
//
v = new ASN1EncodableVector();
for (Iterator i = certs.iterator(); i.hasNext(); ) {
ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream(((X509Certificate) i.next()).getEncoded()));
v.add(tempstream.readObject());
}
DERSet dercertificates = new DERSet(v);
// Create signerinfo structure.
//
ASN1EncodableVector signerinfo = new ASN1EncodableVector();
// Add the signerInfo version
//
signerinfo.add(new ASN1Integer(signerversion));
v = new ASN1EncodableVector();
v.add(getIssuer(signCert.getTBSCertificate()));
v.add(new ASN1Integer(signCert.getSerialNumber()));
signerinfo.add(new DERSequence(v));
// Add the digestAlgorithm
v = new ASN1EncodableVector();
v.add(new ASN1ObjectIdentifier(digestAlgorithm));
v.add(DERNull.INSTANCE);
signerinfo.add(new DERSequence(v));
// add the authenticated attribute if present
if (secondDigest != null && signingTime != null) {
signerinfo.add(new DERTaggedObject(false, 0, getAuthenticatedAttributeSet(secondDigest, signingTime, ocsp)));
}
// Add the digestEncryptionAlgorithm
v = new ASN1EncodableVector();
v.add(new ASN1ObjectIdentifier(digestEncryptionAlgorithm));
v.add(DERNull.INSTANCE);
signerinfo.add(new DERSequence(v));
// Add the digest
signerinfo.add(new DEROctetString(digest));
// Sam found Adobe expects time-stamped SHA1-1 of the encrypted digest
if (tsaClient != null) {
byte[] tsImprint = MessageDigest.getInstance("SHA-1").digest(digest);
byte[] tsToken = tsaClient.getTimeStampToken(this, tsImprint);
if (tsToken != null) {
ASN1EncodableVector unauthAttributes = buildUnauthenticatedAttributes(tsToken);
if (unauthAttributes != null) {
signerinfo.add(new DERTaggedObject(false, 1, new DERSet(unauthAttributes)));
}
}
}
// Finally build the body out of all the components above
ASN1EncodableVector body = new ASN1EncodableVector();
body.add(new ASN1Integer(version));
body.add(new DERSet(digestAlgorithms));
body.add(contentinfo);
body.add(new DERTaggedObject(false, 0, dercertificates));
if (!crls.isEmpty()) {
v = new ASN1EncodableVector();
for (Iterator i = crls.iterator(); i.hasNext(); ) {
ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream(((X509CRL) i.next()).getEncoded()));
v.add(t.readObject());
}
DERSet dercrls = new DERSet(v);
body.add(new DERTaggedObject(false, 1, dercrls));
}
// Only allow one signerInfo
body.add(new DERSet(new DERSequence(signerinfo)));
// Now we have the body, wrap it in it's PKCS7Signed shell
// and return it
//
ASN1EncodableVector whole = new ASN1EncodableVector();
whole.add(new ASN1ObjectIdentifier(ID_PKCS7_SIGNED_DATA));
whole.add(new DERTaggedObject(0, new DERSequence(body)));
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ASN1OutputStream dout = ASN1OutputStream.create(bOut);
dout.writeObject(new DERSequence(whole));
dout.close();
return bOut.toByteArray();
} catch (Exception e) {
throw new ExceptionConverter(e);
}
}
use of org.bouncycastle.asn1.x509.Time in project attestation by TokenScript.
the class Attestor method constructAttestations.
/**
* Constructs a list of X509 attestations to each of the relevant DatasourceName lists of elements
* in the response json.
*
* @param request Json request in a Sring - verification request that was sent to Trulioo Global Gateway†
* @param verifyRecord Json object of the Record in verifyResponse, from Trulioo Global Gateway‡
* @param signature DER encoded signature of exactly the json request string encoded as UTF-8 using a Secp256k1 key with Keccak
* @param userPK user's public key (SubjectPublicKeyInfo object)
* @return List of DER encoded x509 attestations
*
* † An example can be found https://developer.trulioo.com/docs/identity-verification-step-6-verify
* ‡ Observe the "Record" in https://developer.trulioo.com/docs/identity-verification-verify-response
*/
public List<X509CertificateHolder> constructAttestations(String request, JSONObject verifyRecord, byte[] signature, AsymmetricKeyParameter userPK) {
if (!SignatureUtil.verifySha256(request.getBytes(StandardCharsets.UTF_8), signature, userPK)) {
throw ExceptionUtil.throwException(logger, new IllegalArgumentException("Request signature verification failed. " + "Make sure that your message is unaltered, signature is created by hashing the message with SHA256" + "and using a key of secp256k1 type."));
}
List<X509CertificateHolder> res = new ArrayList<>();
Parser parser = new Parser(new JSONObject(request), verifyRecord);
Map<String, X500Name> subjectNames = parser.getX500Names();
Map<String, Extensions> subjectExtensions = parser.getExtensions();
for (String currentAttName : subjectNames.keySet()) {
try {
long time = System.currentTimeMillis();
V3TBSCertificateGenerator certBuilder = new V3TBSCertificateGenerator();
certBuilder.setSignature(serverSigningAlgo);
certBuilder.setIssuer(serverInfo);
certBuilder.setSerialNumber(new ASN1Integer(time));
certBuilder.setStartDate(new Time(new Date(time)));
certBuilder.setEndDate(new Time(new Date(time + lifeTime)));
SubjectPublicKeyInfo spki = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(userPK);
// // todo hack to create a valid spki without ECNamedParameters
// spki = new SubjectPublicKeyInfo(new AlgorithmIdentifier(new ASN1ObjectIdentifier(OID_ECDSA)),
// spki.getPublicKeyData());
certBuilder.setSubjectPublicKeyInfo(spki);
certBuilder.setSubject(subjectNames.get(currentAttName));
certBuilder.setExtensions(subjectExtensions.get(currentAttName));
TBSCertificate tbsCert = certBuilder.generateTBSCertificate();
res.add(new X509CertificateHolder(constructSignedAttestation(tbsCert)));
// To ensure that we get a new serial number for every cert
Thread.sleep(1);
} catch (IOException e) {
throw ExceptionUtil.makeRuntimeException(logger, "Could not parse server key", e);
} catch (InterruptedException e) {
throw ExceptionUtil.makeRuntimeException(logger, "Could not sleep", e);
}
}
return res;
}
use of org.bouncycastle.asn1.x509.Time in project staplr by pridiltal.
the class PdfPKCS7 method getAuthenticatedAttributeBytes.
/**
* When using authenticatedAttributes the authentication process is different.
* The document digest is generated and put inside the attribute. The signing is done over the DER encoded
* authenticatedAttributes. This method provides that encoding and the parameters must be
* exactly the same as in {@link #getEncodedPKCS7(byte[],Calendar)}.
* <p>
* A simple example:
* <p>
* <pre>
* Calendar cal = Calendar.getInstance();
* PdfPKCS7 pk7 = new PdfPKCS7(key, chain, null, "SHA1", null, false);
* MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
* byte buf[] = new byte[8192];
* int n;
* InputStream inp = sap.getRangeStream();
* while ((n = inp.read(buf)) > 0) {
* messageDigest.update(buf, 0, n);
* }
* byte hash[] = messageDigest.digest();
* byte sh[] = pk7.getAuthenticatedAttributeBytes(hash, cal);
* pk7.update(sh, 0, sh.length);
* byte sg[] = pk7.getEncodedPKCS7(hash, cal);
* </pre>
* @param secondDigest the content digest
* @param signingTime the signing time
* @return the byte array representation of the authenticatedAttributes ready to be signed
*/
public byte[] getAuthenticatedAttributeBytes(byte[] secondDigest, Calendar signingTime) {
try {
ASN1EncodableVector attribute = new ASN1EncodableVector();
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(new ASN1ObjectIdentifier(ID_CONTENT_TYPE));
v.add(new DERSet(new ASN1ObjectIdentifier(ID_PKCS7_DATA)));
attribute.add(new DERSequence(v));
v = new ASN1EncodableVector();
v.add(new ASN1ObjectIdentifier(ID_SIGNING_TIME));
v.add(new DERSet(new DERUTCTime(signingTime.getTime())));
attribute.add(new DERSequence(v));
v = new ASN1EncodableVector();
v.add(new ASN1ObjectIdentifier(ID_MESSAGE_DIGEST));
v.add(new DERSet(new DEROctetString(secondDigest)));
attribute.add(new DERSequence(v));
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ASN1OutputStream dout = new ASN1OutputStream(bOut);
dout.writeObject(new DERSet(attribute));
dout.close();
return bOut.toByteArray();
} catch (Exception e) {
throw new ExceptionConverter(e);
}
}
use of org.bouncycastle.asn1.x509.Time in project dodo by devhawala.
the class AuthChsCommon method checkStrongCredentials.
/**
* Check that the strong credentials and the strong verifier are
* both valid for the recipient on the given machine.
*
* @param chsDatabase the clearinghouse database to check against
* @param credentials the credentials to verify
* @param verifier the verifier going with the credentials
* @param recipient the recipient for which the the strong credentials are encoded
* @param recipientMachineId the target machine for which the verifier is encoded
* @param decodedConversationKey target where to store the conversation encryption key for
* the session (the key will only be stored there if not {@code null} and at least
* 4 entries long).
* @return {@code null} if the credentials is not of strong type or the
* initiator encoded in the credentials is invalid or if the expiration time
* of the credentials are expired or the verifier timestamp is invalid;
* else the Clearinghouse name of the user if the credentials passed the tests.
* @throws EndOfMessageException if decoding the credentials or verifier after
* decryption fails
* @throws IllegalArgumentException if the recipient is invalid or has no
* strong password for decryption
* @throws Exception if any decryption fails
*/
public static ThreePartName checkStrongCredentials(ChsDatabase chsDatabase, Credentials credentials, Verifier verifier, ThreePartName recipient, long recipientMachineId, int[] decodedConversationKey, StrongVerifier decodedVerifier) throws Exception {
// get the recipient decryption password
if (credentials.type.get() != CredentialsType.strong) {
return null;
}
byte[] recipientStrongPw = chsDatabase.getStrongPassword(recipient);
if (recipientStrongPw == null) {
throw new IllegalArgumentException("Invalid recipient (strong password not found)");
}
int[] recipientDecryptPw = StrongAuthUtils.toWords(recipientStrongPw);
// decode the credentials with the recipient's strong password
StrongCredentials creds = StrongCredentials.make();
decryptFrom(recipientDecryptPw, credentials.value, creds);
// decrypt the verifier
if (decodedConversationKey == null || decodedConversationKey.length < 4) {
decodedConversationKey = new int[4];
}
decodedConversationKey[0] = creds.conversationKey.get(0).get();
decodedConversationKey[1] = creds.conversationKey.get(1).get();
decodedConversationKey[2] = creds.conversationKey.get(2).get();
decodedConversationKey[3] = creds.conversationKey.get(3).get();
StrongVerifier verfr = StrongVerifier.make();
decryptFrom(decodedConversationKey, verifier, verfr);
// left justified machine-id => upper 32 bits
long rcptTimestampMachineId32Bits = (recipientMachineId >> 16) & 0xFFFFFFFFL;
// left justified machine-id => lower 32 bits
long rcptTicksMachineId32Bits = (recipientMachineId & 0x0000FFFFL) << 16;
long verifierTicks = verfr.ticks.get() ^ rcptTicksMachineId32Bits;
long verifierTimestamp = verfr.timeStamp.get() ^ rcptTimestampMachineId32Bits;
if (decodedVerifier != null) {
decodedVerifier.ticks.set(verifierTicks);
decodedVerifier.timeStamp.set(verifierTimestamp);
}
// (temp) log the relevant data
Time now = Time.make().now();
System.out.printf("creds.initiator: %s:%s:%s\n", creds.initiator.object.get(), creds.initiator.domain.get(), creds.initiator.organization.get());
System.out.printf("creds.expiration: %d (now: %d)\n", creds.expirationTime.get(), now.get());
System.out.printf("verifier.timeStamp: 0x%08X = %d -> xor-ed(machineId): 0x%08X = %s (now: 0x%08X = %d)\n", verfr.timeStamp.get(), verfr.timeStamp.get(), verifierTimestamp, verifierTimestamp, now.get(), now.get());
System.out.printf("verifier.ticks: 0x%08X = %d -> xor-ed(machineId): 0x%08X = %d\n", verfr.ticks.get(), verfr.ticks.get(), verifierTicks, verifierTicks);
// check the credentials / verifier
if (!chsDatabase.isValidName(creds.initiator)) {
System.out.println("** checkStrongCredentials() => ERR: creds.initiator is not a valid name");
return null;
}
boolean skipTimestampChecks = MachineIds.getCfgBoolean(credentials.remoteHostId.get(), MachineIds.CFG_AUTH_SKIP_TIMESTAMP_CHECKS, false);
if (!skipTimestampChecks) {
if (now.get() > creds.expirationTime.get()) {
System.out.println("** checkStrongCredentials() => ERR: now > creds.expirationTime");
return null;
}
if (now.get() < verifierTimestamp) {
System.out.println("** checkStrongCredentials() => ERR: now < verifierTimestamp");
return null;
}
if (now.get() > (verifierTimestamp + 60)) {
System.out.println("** checkStrongCredentials() => ERR: now > verifierTimestamp+60secs");
return null;
}
} else {
System.out.println("** checkStrongCredentials() => timestamp checks skipped (creds.expirationTime, verifier.timestamp)");
}
System.out.println("** checkStrongCredentials() => strong credentials OK");
return new ThreePartName().from(creds.initiator);
}
Aggregations