Search in sources :

Example 1 with PKIHeader

use of com.github.zhenwei.pkix.util.asn1.cmp.PKIHeader in project ca3sCore by kuehne-trustable-de.

the class CaCmpConnector method readCertResponse.

/**
 * @param responseBytes
 * @param pkiMessageReq
 * @param csr
 * @param config
 * @throws IOException
 * @throws CRMFException
 * @throws CMPException
 * @throws GeneralSecurityException
 */
public de.trustable.ca3s.core.domain.Certificate readCertResponse(final byte[] responseBytes, final PKIMessage pkiMessageReq, final CSR csr, final CAConnectorConfig config) throws IOException, CRMFException, CMPException, GeneralSecurityException {
    final ASN1Primitive derObject = cryptoUtil.getDERObject(responseBytes);
    final PKIMessage pkiMessage = PKIMessage.getInstance(derObject);
    if (pkiMessage == null) {
        throw new GeneralSecurityException("No CMP message could be parsed from received Der object.");
    }
    printPKIMessageInfo(pkiMessage);
    PKIHeader pkiHeaderReq = pkiMessageReq.getHeader();
    PKIHeader pkiHeaderResp = pkiMessage.getHeader();
    if (!pkiHeaderReq.getSenderNonce().equals(pkiHeaderResp.getRecipNonce())) {
        ASN1OctetString asn1Oct = pkiHeaderResp.getRecipNonce();
        if (asn1Oct == null) {
            LOGGER.info("Recip nonce  == null");
        } else {
            LOGGER.info("sender nonce " + java.util.Base64.getEncoder().encodeToString(pkiHeaderReq.getSenderNonce().getOctets()) + " != " + java.util.Base64.getEncoder().encodeToString(asn1Oct.getOctets()));
        }
        throw new GeneralSecurityException("Sender / Recip nonce mismatch");
    }
    if (!pkiHeaderReq.getTransactionID().equals(pkiHeaderResp.getTransactionID())) {
        ASN1OctetString asn1Oct = pkiHeaderResp.getTransactionID();
        if (asn1Oct == null) {
            LOGGER.info("transaction id == null");
        } else {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("transaction id " + java.util.Base64.getEncoder().encodeToString(pkiHeaderReq.getTransactionID().getOctets()) + " != " + java.util.Base64.getEncoder().encodeToString(asn1Oct.getOctets()));
            }
        }
        throw new GeneralSecurityException("Sender / Recip Transaction Id mismatch");
    }
    final PKIBody body = pkiMessage.getBody();
    int tagno = body.getType();
    if (tagno == PKIBody.TYPE_ERROR) {
        handleCMPError(body);
    } else if (tagno == PKIBody.TYPE_CERT_REP || tagno == PKIBody.TYPE_INIT_REP) {
        // certificate successfully generated
        CertRepMessage certRepMessage = CertRepMessage.getInstance(body.getContent());
        try {
            // CMPCertificate[] cmpCertArr = certRepMessage.getCaPubs();
            CMPCertificate[] cmpCertArr = pkiMessage.getExtraCerts();
            LOGGER.info("CMP Response body contains " + cmpCertArr.length + " extra certificates");
            for (int i = 0; i < cmpCertArr.length; i++) {
                CMPCertificate cmpCert = cmpCertArr[i];
                LOGGER.info("Added CA '" + cmpCert.getX509v3PKCert().getSubject() + "' from CMP Response body");
                de.trustable.ca3s.core.domain.Certificate certDao = certUtil.createCertificate(cmpCert.getEncoded(), null, null, true);
                certificateRepository.save(certDao);
                LOGGER.debug("Additional CA '" + certDao.getSubject() + "' from CMP Response body");
            }
        } catch (NullPointerException npe) {
        // NOSONAR
        // just ignore
        }
        CertResponse[] respArr = certRepMessage.getResponse();
        if (respArr == null || (respArr.length == 0)) {
            throw new GeneralSecurityException("No CMP response found.");
        }
        LOGGER.info("CMP Response body contains " + respArr.length + " elements");
        for (int i = 0; i < respArr.length; i++) {
            if (respArr[i] == null) {
                throw new GeneralSecurityException("No CMP response returned.");
            }
            BigInteger status = BigInteger.ZERO;
            String statusText = "";
            PKIStatusInfo pkiStatusInfo = respArr[i].getStatus();
            if (pkiStatusInfo != null) {
                PKIFreeText freeText = pkiStatusInfo.getStatusString();
                if (freeText != null) {
                    for (int j = 0; j < freeText.size(); j++) {
                        statusText = freeText.getStringAt(j) + "\n";
                    }
                }
            }
            if ((respArr[i].getCertifiedKeyPair() == null) || (respArr[i].getCertifiedKeyPair().getCertOrEncCert() == null)) {
                csrUtil.setStatus(csr, CsrStatus.REJECTED);
                csrUtil.setCsrAttribute(csr, CsrAttribute.ATTRIBUTE_FAILURE_INFO, statusText, true);
                throw new GeneralSecurityException("CMP response contains no certificate, status :" + status + "\n" + statusText);
            }
            CMPCertificate cmpCert = respArr[i].getCertifiedKeyPair().getCertOrEncCert().getCertificate();
            if (cmpCert != null) {
                org.bouncycastle.asn1.x509.Certificate cmpCertificate = cmpCert.getX509v3PKCert();
                if (cmpCertificate != null) {
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("#" + i + ": " + cmpCertificate);
                    }
                    final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", "BC");
                    /*
						 * version returning just the end entity ...
						 */
                    final Collection<? extends java.security.cert.Certificate> certificateChain = certificateFactory.generateCertificates(new ByteArrayInputStream(cmpCertificate.getEncoded()));
                    X509Certificate[] certArray = certificateChain.toArray(new X509Certificate[0]);
                    X509Certificate cert = certArray[0];
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.info("#" + i + ": " + cert);
                    }
                    de.trustable.ca3s.core.domain.Certificate certDao = certUtil.createCertificate(cert.getEncoded(), csr, null, false);
                    certDao.setRevocationCA(config);
                    certificateRepository.save(certDao);
                    return certDao;
                }
            }
        }
    } else {
        throw new GeneralSecurityException("unexpected PKI body type :" + tagno);
    }
    return null;
}
Also used : PKIMessage(org.bouncycastle.asn1.cmp.PKIMessage) PKIHeader(org.bouncycastle.asn1.cmp.PKIHeader) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) PKIBody(org.bouncycastle.asn1.cmp.PKIBody) GeneralSecurityException(java.security.GeneralSecurityException) PKIStatusInfo(org.bouncycastle.asn1.cmp.PKIStatusInfo) CertRepMessage(org.bouncycastle.asn1.cmp.CertRepMessage) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) CertificateFactory(java.security.cert.CertificateFactory) X509Certificate(java.security.cert.X509Certificate) PKIFreeText(org.bouncycastle.asn1.cmp.PKIFreeText) CMPCertificate(org.bouncycastle.asn1.cmp.CMPCertificate) ByteArrayInputStream(java.io.ByteArrayInputStream) BigInteger(java.math.BigInteger) Collection(java.util.Collection) ASN1Primitive(org.bouncycastle.asn1.ASN1Primitive) X509Certificate(java.security.cert.X509Certificate) CMPCertificate(org.bouncycastle.asn1.cmp.CMPCertificate) Certificate(de.trustable.ca3s.core.domain.Certificate)

Example 2 with PKIHeader

use of com.github.zhenwei.pkix.util.asn1.cmp.PKIHeader in project ca3sCore by kuehne-trustable-de.

the class CaCmpConnector method printPKIMessageInfo.

/**
 * @param pkiMessage
 */
private void printPKIMessageInfo(final PKIMessage pkiMessage) {
    final PKIHeader header = pkiMessage.getHeader();
    final PKIBody body = pkiMessage.getBody();
    int tagno = body.getType();
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Received CMP message with pvno=" + header.getPvno() + ", sender=" + header.getSender().toString() + ", recipient=" + header.getRecipient().toString());
        LOGGER.debug("Body is of type: " + tagno);
        LOGGER.debug("Transaction id: " + header.getTransactionID());
    }
}
Also used : PKIHeader(org.bouncycastle.asn1.cmp.PKIHeader) PKIBody(org.bouncycastle.asn1.cmp.PKIBody)

Example 3 with PKIHeader

use of com.github.zhenwei.pkix.util.asn1.cmp.PKIHeader in project xipki by xipki.

the class CmpCaClient method transmit.

private PKIMessage transmit(ProtectedPKIMessage request) throws Exception {
    byte[] encodedResponse = send(request.toASN1Structure().getEncoded());
    GeneralPKIMessage response = new GeneralPKIMessage(encodedResponse);
    PKIHeader reqHeader = request.getHeader();
    PKIHeader respHeader = response.getHeader();
    ASN1OctetString tid = reqHeader.getTransactionID();
    if (!tid.equals(respHeader.getTransactionID())) {
        throw new Exception("response.transactionId != request.transactionId");
    }
    ASN1OctetString senderNonce = reqHeader.getSenderNonce();
    if (!senderNonce.equals(respHeader.getRecipNonce())) {
        throw new Exception("response.recipientNonce != request.senderNonce");
    }
    GeneralName rec = respHeader.getRecipient();
    if (!requestorSubject.equals(rec)) {
        throw new Exception("unknown CMP requestor " + rec.toString());
    }
    if (!response.hasProtection()) {
        PKIBody respBody = response.getBody();
        int bodyType = respBody.getType();
        if (bodyType != PKIBody.TYPE_ERROR) {
            throw new Exception("response is not signed");
        }
    }
    if (verifyProtection(response)) {
        return response.toASN1Structure();
    }
    throw new Exception("invalid signature in PKI protection");
}
Also used : PKIHeader(org.bouncycastle.asn1.cmp.PKIHeader) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) PKIBody(org.bouncycastle.asn1.cmp.PKIBody) GeneralName(org.bouncycastle.asn1.x509.GeneralName) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) CMPException(org.bouncycastle.cert.cmp.CMPException) InvalidKeyException(java.security.InvalidKeyException) IOException(java.io.IOException) GeneralPKIMessage(org.bouncycastle.cert.cmp.GeneralPKIMessage)

Example 4 with PKIHeader

use of com.github.zhenwei.pkix.util.asn1.cmp.PKIHeader in project xipki by xipki.

the class CmpCaClient method verifyProtection.

// method extractGeneralRepContent
private boolean verifyProtection(GeneralPKIMessage pkiMessage) throws CMPException, InvalidKeyException {
    ProtectedPKIMessage protectedMsg = new ProtectedPKIMessage(pkiMessage);
    if (protectedMsg.hasPasswordBasedMacProtection()) {
        LOG.warn("protection is not signature based: " + pkiMessage.getHeader().getProtectionAlg().getAlgorithm().getId());
        return false;
    }
    PKIHeader header = protectedMsg.getHeader();
    if (!header.getSender().equals(responderSubject)) {
        LOG.warn("not authorized responder '{}'", header.getSender());
        return false;
    }
    String algOid = protectedMsg.getHeader().getProtectionAlg().getAlgorithm().getId();
    if (!trustedProtectionAlgOids.contains(algOid)) {
        LOG.warn("PKI protection algorithm is untrusted '{}'", algOid);
        return false;
    }
    ContentVerifierProvider verifierProvider = getContentVerifierProvider(responderCert.getPublicKey());
    if (verifierProvider == null) {
        LOG.warn("not authorized responder '{}'", header.getSender());
        return false;
    }
    return protectedMsg.verify(verifierProvider);
}
Also used : PKIHeader(org.bouncycastle.asn1.cmp.PKIHeader) ProtectedPKIMessage(org.bouncycastle.cert.cmp.ProtectedPKIMessage) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DEROctetString(org.bouncycastle.asn1.DEROctetString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider)

Example 5 with PKIHeader

use of com.github.zhenwei.pkix.util.asn1.cmp.PKIHeader in project xipki by xipki.

the class CmpResponder method verifyProtection.

private ProtectionVerificationResult verifyProtection(String tid, GeneralPKIMessage pkiMessage, CmpControl cmpControl) throws CMPException, InvalidKeyException, OperatorCreationException {
    ProtectedPKIMessage protectedMsg = new ProtectedPKIMessage(pkiMessage);
    if (protectedMsg.hasPasswordBasedMacProtection()) {
        LOG.warn("NOT_SIGNAUTRE_BASED: {}", pkiMessage.getHeader().getProtectionAlg().getAlgorithm().getId());
        return new ProtectionVerificationResult(null, ProtectionResult.NOT_SIGNATURE_BASED);
    }
    PKIHeader header = protectedMsg.getHeader();
    AlgorithmIdentifier protectionAlg = header.getProtectionAlg();
    if (!cmpControl.getSigAlgoValidator().isAlgorithmPermitted(protectionAlg)) {
        LOG.warn("SIG_ALGO_FORBIDDEN: {}", pkiMessage.getHeader().getProtectionAlg().getAlgorithm().getId());
        return new ProtectionVerificationResult(null, ProtectionResult.SIGALGO_FORBIDDEN);
    }
    CmpRequestorInfo requestor = getRequestor(header);
    if (requestor == null) {
        LOG.warn("tid={}: not authorized requestor '{}'", tid, header.getSender());
        return new ProtectionVerificationResult(null, ProtectionResult.SENDER_NOT_AUTHORIZED);
    }
    ContentVerifierProvider verifierProvider = securityFactory.getContentVerifierProvider(requestor.getCert().getCert());
    if (verifierProvider == null) {
        LOG.warn("tid={}: not authorized requestor '{}'", tid, header.getSender());
        return new ProtectionVerificationResult(requestor, ProtectionResult.SENDER_NOT_AUTHORIZED);
    }
    boolean signatureValid = protectedMsg.verify(verifierProvider);
    return new ProtectionVerificationResult(requestor, signatureValid ? ProtectionResult.VALID : ProtectionResult.INVALID);
}
Also used : PKIHeader(org.bouncycastle.asn1.cmp.PKIHeader) ProtectedPKIMessage(org.bouncycastle.cert.cmp.ProtectedPKIMessage) ProtectionVerificationResult(org.xipki.cmp.ProtectionVerificationResult) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider)

Aggregations

PKIHeader (org.bouncycastle.asn1.cmp.PKIHeader)19 PKIBody (org.bouncycastle.asn1.cmp.PKIBody)13 PKIMessage (org.bouncycastle.asn1.cmp.PKIMessage)12 ProtectedPKIMessage (org.bouncycastle.cert.cmp.ProtectedPKIMessage)9 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)8 IOException (java.io.IOException)6 GeneralPKIMessage (org.bouncycastle.cert.cmp.GeneralPKIMessage)6 DEROctetString (org.bouncycastle.asn1.DEROctetString)5 InfoTypeAndValue (org.bouncycastle.asn1.cmp.InfoTypeAndValue)4 GeneralName (org.bouncycastle.asn1.x509.GeneralName)4 CMPException (org.bouncycastle.cert.cmp.CMPException)4 ProtectionVerificationResult (org.xipki.cmp.ProtectionVerificationResult)4 InvalidKeyException (java.security.InvalidKeyException)3 Date (java.util.Date)3 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)3 DERUTF8String (org.bouncycastle.asn1.DERUTF8String)3 PKIFreeText (org.bouncycastle.asn1.cmp.PKIFreeText)3 ContentVerifierProvider (org.bouncycastle.operator.ContentVerifierProvider)3 OperatorCreationException (org.bouncycastle.operator.OperatorCreationException)3 DERBitString (com.github.zhenwei.core.asn1.DERBitString)2