Example usage for org.bouncycastle.asn1.cmp PKIHeader getTransactionID

List of usage examples for org.bouncycastle.asn1.cmp PKIHeader getTransactionID

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.cmp PKIHeader getTransactionID.

Prototype

public ASN1OctetString getTransactionID() 

Source Link

Usage

From source file:org.ejbca.core.protocol.cmp.CmpMessageDispatcherSessionBean.java

License:Open Source License

/** The message may have been received by any transport protocol, and is passed here in it's binary ASN.1 form.
 * /*  www  .  j a va2  s  .co  m*/
 * @param message der encoded CMP message
 * @return IResponseMessage containing the CMP response message or null if there is no message to send back or some internal error has occurred
 */
private ResponseMessage dispatch(final AuthenticationToken admin, final ASN1Primitive derObject,
        final boolean authenticated, String confAlias) {

    this.cmpConfiguration = (CmpConfiguration) this.globalConfigSession
            .getCachedConfiguration(CmpConfiguration.CMP_CONFIGURATION_ID);

    if (!cmpConfiguration.aliasExists(confAlias)) {
        log.info("There is no CMP alias: " + confAlias);
        return CmpMessageHelper.createUnprotectedErrorMessage(null, ResponseStatus.FAILURE,
                FailInfo.INCORRECT_DATA, "Wrong URL. CMP alias '" + confAlias + "' does not exist");
    }

    final PKIMessage req;
    try {
        req = PKIMessage.getInstance(derObject);
        if (req == null) {
            throw new Exception("No CMP message could be parsed from received Der object.");
        }
    } catch (Throwable t) { // NOPMD: catch all to report errors back to client
        final String eMsg = intres.getLocalizedMessage("cmp.errornotcmpmessage");
        log.error(eMsg, t);
        // If we could not read the message, we should return an error BAD_REQUEST
        return CmpMessageHelper.createUnprotectedErrorMessage(null, ResponseStatus.FAILURE,
                FailInfo.BAD_REQUEST, eMsg);
    }
    try {
        final PKIBody body = req.getBody();
        final int tagno = body.getType();
        if (log.isDebugEnabled()) {
            final PKIHeader header = req.getHeader();
            log.debug("Received CMP message with pvno=" + header.getPvno() + ", sender="
                    + header.getSender().toString() + ", recipient=" + header.getRecipient().toString());
            log.debug("Cmp configuration alias: " + confAlias);
            log.debug("The CMP message is already authenticated: " + authenticated);
            log.debug("Body is of type: " + tagno);
            log.debug("Transaction id: " + header.getTransactionID());
            //log.debug(ASN1Dump.dumpAsString(req));
        }

        BaseCmpMessage cmpMessage = null;
        ICmpMessageHandler handler = null;
        int unknownMessageType = -1;
        switch (tagno) {
        case 0:
            // 0 (ir, Initialization Request) and 2 (cr, Certification Req) are both certificate requests
            handler = new CrmfMessageHandler(admin, confAlias, caSession, certificateProfileSession,
                    certificateRequestSession, endEntityAccessSession, endEntityProfileSession, signSession,
                    certificateStoreSession, authSession, authenticationProviderSession,
                    endEntityManagementSession, globalConfigSession);
            cmpMessage = new CrmfRequestMessage(req, this.cmpConfiguration.getCMPDefaultCA(confAlias),
                    this.cmpConfiguration.getAllowRAVerifyPOPO(confAlias),
                    this.cmpConfiguration.getExtractUsernameComponent(confAlias));
            break;
        case 2:
            handler = new CrmfMessageHandler(admin, confAlias, caSession, certificateProfileSession,
                    certificateRequestSession, endEntityAccessSession, endEntityProfileSession, signSession,
                    certificateStoreSession, authSession, authenticationProviderSession,
                    endEntityManagementSession, globalConfigSession);
            cmpMessage = new CrmfRequestMessage(req, this.cmpConfiguration.getCMPDefaultCA(confAlias),
                    this.cmpConfiguration.getAllowRAVerifyPOPO(confAlias),
                    this.cmpConfiguration.getExtractUsernameComponent(confAlias));
            break;
        case 7:
            // Key Update request (kur, Key Update Request)
            handler = new CrmfKeyUpdateHandler(admin, confAlias, caSession, certificateProfileSession,
                    endEntityAccessSession, endEntityProfileSession, signSession, certificateStoreSession,
                    authSession, authenticationProviderSession, endEntityManagementSession,
                    globalConfigSession);
            cmpMessage = new CrmfRequestMessage(req, this.cmpConfiguration.getCMPDefaultCA(confAlias),
                    this.cmpConfiguration.getAllowRAVerifyPOPO(confAlias),
                    this.cmpConfiguration.getExtractUsernameComponent(confAlias));
            break;
        case 19:
            // PKI confirm (pkiconf, Confirmation)
        case 24:
            // Certificate confirmation (certConf, Certificate confirm)
            handler = new ConfirmationMessageHandler(admin, confAlias, caSession, endEntityProfileSession,
                    certificateProfileSession, authSession, authenticationProviderSession, cryptoTokenSession,
                    globalConfigSession);
            cmpMessage = new GeneralCmpMessage(req);
            break;
        case 11:
            // Revocation request (rr, Revocation Request)
            handler = new RevocationMessageHandler(admin, confAlias, endEntityManagementSession, caSession,
                    endEntityProfileSession, certificateProfileSession, certificateStoreSession, authSession,
                    endEntityAccessSession, authenticationProviderSession, cryptoTokenSession,
                    globalConfigSession);
            cmpMessage = new GeneralCmpMessage(req);
            break;
        case 20:
            // NestedMessageContent (nested)
            if (log.isDebugEnabled()) {
                log.debug("Received a NestedMessageContent");
            }

            final NestedMessageContent nestedMessage = new NestedMessageContent(req, confAlias,
                    globalConfigSession);
            if (nestedMessage.verify()) {
                if (log.isDebugEnabled()) {
                    log.debug("The NestedMessageContent was verified successfully");
                }
                try {
                    PKIMessages nestesMessages = (PKIMessages) nestedMessage.getPKIMessage().getBody()
                            .getContent();
                    PKIMessage msg = nestesMessages.toPKIMessageArray()[0];
                    return dispatch(admin, msg.toASN1Primitive(), true, confAlias);
                } catch (IllegalArgumentException e) {
                    final String errMsg = e.getLocalizedMessage();
                    log.info(errMsg, e);
                    cmpMessage = new NestedMessageContent(req, confAlias, globalConfigSession);
                    return CmpMessageHelper.createUnprotectedErrorMessage(cmpMessage, ResponseStatus.FAILURE,
                            FailInfo.BAD_REQUEST, errMsg);
                }
            } else {
                final String errMsg = "Could not verify the RA, signature verification on NestedMessageContent failed.";
                log.info(errMsg);
                cmpMessage = new NestedMessageContent(req, confAlias, globalConfigSession);
                return CmpMessageHelper.createUnprotectedErrorMessage(cmpMessage, ResponseStatus.FAILURE,
                        FailInfo.BAD_REQUEST, errMsg);
            }

        default:
            unknownMessageType = tagno;
            log.info("Received an unknown message type, tagno=" + tagno);
            break;
        }
        if (handler == null || cmpMessage == null) {
            if (unknownMessageType > -1) {
                final String eMsg = intres.getLocalizedMessage("cmp.errortypenohandle",
                        Integer.valueOf(unknownMessageType));
                log.error(eMsg);
                return CmpMessageHelper.createUnprotectedErrorMessage(null, ResponseStatus.FAILURE,
                        FailInfo.BAD_REQUEST, eMsg);
            }
            throw new Exception("Something is null! Handler=" + handler + ", cmpMessage=" + cmpMessage);
        }
        final ResponseMessage ret = handler.handleMessage(cmpMessage, authenticated);
        if (ret != null) {
            log.debug("Received a response message of type '" + ret.getClass().getName()
                    + "' from CmpMessageHandler.");
        } else {
            log.error(intres.getLocalizedMessage("cmp.errorresponsenull"));
        }
        return ret;
    } catch (Exception e) {
        log.error(intres.getLocalizedMessage("cmp.errorprocess"), e);
        return null;
    }
}

From source file:org.ejbca.core.protocol.cmp.CmpMessageHelper.java

License:Open Source License

public static PKIHeaderBuilder getHeaderBuilder(PKIHeader head) {
    PKIHeaderBuilder builder = new PKIHeaderBuilder(head.getPvno().getValue().intValue(), head.getSender(),
            head.getRecipient());//from   w  ww.java 2 s  .com
    builder.setFreeText(head.getFreeText());
    builder.setGeneralInfo(head.getGeneralInfo());
    builder.setMessageTime(head.getMessageTime());
    builder.setRecipKID((DEROctetString) head.getRecipKID());
    builder.setRecipNonce(head.getRecipNonce());
    builder.setSenderKID(head.getSenderKID());
    builder.setSenderNonce(head.getSenderNonce());
    builder.setTransactionID(head.getTransactionID());
    return builder;
}

From source file:org.ejbca.core.protocol.cmp.CmpTestCase.java

License:Open Source License

protected static void checkCmpResponseGeneral(byte[] retMsg, String issuerDN, X500Name userDN,
        Certificate cacert, byte[] senderNonce, byte[] transId, boolean signed, String pbeSecret,
        String expectedSignAlg)// w w  w . j ava  2 s  .c  o  m
        throws IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException {
    assertNotNull("No response from server.", retMsg);
    assertTrue("Response was of 0 length.", retMsg.length > 0);
    boolean pbe = (pbeSecret != null);
    //
    // Parse response message
    //
    ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(retMsg));
    PKIMessage respObject = null;
    try {
        respObject = PKIMessage.getInstance(asn1InputStream.readObject());
    } finally {
        asn1InputStream.close();
    }
    assertNotNull(respObject);

    // The signer, i.e. the CA, check it's the right CA
    PKIHeader header = respObject.getHeader();

    // Check that the message is signed with the correct digest alg
    if (StringUtils.isEmpty(expectedSignAlg)) {
        expectedSignAlg = PKCSObjectIdentifiers.sha1WithRSAEncryption.getId();
    }
    // if cacert is ECDSA we should expect an ECDSA signature alg
    //if (AlgorithmTools.getSignatureAlgorithm(cacert).contains("ECDSA")) {
    //    expectedSignAlg = X9ObjectIdentifiers.ecdsa_with_SHA1.getId();
    //} else if(AlgorithmTools.getSignatureAlgorithm(cacert).contains("ECGOST3410")) {
    //    expectedSignAlg = CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001.getId();
    //} else if(AlgorithmTools.getSignatureAlgorithm(cacert).contains("DSTU4145")) {
    //    expectedSignAlg = (new ASN1ObjectIdentifier(CesecoreConfiguration.getOidDstu4145())).getId();
    //}
    if (signed) {
        AlgorithmIdentifier algId = header.getProtectionAlg();
        assertNotNull(
                "Protection algorithm was null when expecting a signed response, this was propably an unprotected error message: "
                        + header.getFreeText(),
                algId);
        assertEquals(expectedSignAlg, algId.getAlgorithm().getId());
    }
    if (pbe) {
        AlgorithmIdentifier algId = header.getProtectionAlg();
        assertNotNull(
                "Protection algorithm was null when expecting a pbe protected response, this was propably an unprotected error message: "
                        + header.getFreeText(),
                algId);
        assertEquals("Protection algorithm id: " + algId.getAlgorithm().getId(),
                CMPObjectIdentifiers.passwordBasedMac.getId(), algId.getAlgorithm().getId()); // 1.2.840.113549.1.1.5 - SHA-1 with RSA Encryption
    }

    // Check that the signer is the expected CA    
    assertEquals(header.getSender().getTagNo(), 4);

    X500Name expissuer = new X500Name(issuerDN);
    X500Name actissuer = new X500Name(header.getSender().getName().toString());
    assertEquals(expissuer, actissuer);
    if (signed) {
        // Verify the signature
        byte[] protBytes = CmpMessageHelper.getProtectedBytes(respObject);
        DERBitString bs = respObject.getProtection();
        Signature sig;
        try {
            sig = Signature.getInstance(expectedSignAlg, "BC");
            sig.initVerify(cacert);
            sig.update(protBytes);
            boolean ret = sig.verify(bs.getBytes());
            assertTrue(ret);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            assertTrue(false);
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
            assertTrue(false);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
            assertTrue(false);
        } catch (SignatureException e) {
            e.printStackTrace();
            assertTrue(false);
        }
    }
    if (pbe) {
        ASN1OctetString os = header.getSenderKID();
        assertNotNull(os);
        String keyId = CmpMessageHelper.getStringFromOctets(os);
        log.debug("Found a sender keyId: " + keyId);
        // Verify the PasswordBased protection of the message
        byte[] protectedBytes = CmpMessageHelper.getProtectedBytes(respObject);
        DERBitString protection = respObject.getProtection();
        AlgorithmIdentifier pAlg = header.getProtectionAlg();
        log.debug("Protection type is: " + pAlg.getAlgorithm().getId());
        PBMParameter pp = PBMParameter.getInstance(pAlg.getParameters());
        int iterationCount = pp.getIterationCount().getPositiveValue().intValue();
        log.debug("Iteration count is: " + iterationCount);
        AlgorithmIdentifier owfAlg = pp.getOwf();
        // Normal OWF alg is 1.3.14.3.2.26 - SHA1
        log.debug("Owf type is: " + owfAlg.getAlgorithm().getId());
        AlgorithmIdentifier macAlg = pp.getMac();
        // Normal mac alg is 1.3.6.1.5.5.8.1.2 - HMAC/SHA1
        log.debug("Mac type is: " + macAlg.getAlgorithm().getId());
        byte[] salt = pp.getSalt().getOctets();
        // log.info("Salt is: "+new String(salt));
        byte[] raSecret = pbeSecret != null ? pbeSecret.getBytes() : new byte[0];
        byte[] basekey = new byte[raSecret.length + salt.length];
        System.arraycopy(raSecret, 0, basekey, 0, raSecret.length);
        for (int i = 0; i < salt.length; i++) {
            basekey[raSecret.length + i] = salt[i];
        }
        // Construct the base key according to rfc4210, section 5.1.3.1
        MessageDigest dig = MessageDigest.getInstance(owfAlg.getAlgorithm().getId(),
                BouncyCastleProvider.PROVIDER_NAME);
        for (int i = 0; i < iterationCount; i++) {
            basekey = dig.digest(basekey);
            dig.reset();
        }
        // HMAC/SHA1 os normal 1.3.6.1.5.5.8.1.2 or 1.2.840.113549.2.7
        String macOid = macAlg.getAlgorithm().getId();
        Mac mac = Mac.getInstance(macOid, BouncyCastleProvider.PROVIDER_NAME);
        SecretKey key = new SecretKeySpec(basekey, macOid);
        mac.init(key);
        mac.reset();
        mac.update(protectedBytes, 0, protectedBytes.length);
        byte[] out = mac.doFinal();
        // My out should now be the same as the protection bits
        byte[] pb = protection.getBytes();
        boolean ret = Arrays.equals(out, pb);
        assertTrue(ret);
    }

    // --SenderNonce
    // SenderNonce is something the server came up with, but it should be 16
    // chars
    byte[] nonce = header.getSenderNonce().getOctets();
    assertEquals(nonce.length, 16);

    // --Recipient Nonce
    // recipient nonce should be the same as we sent away as sender nonce
    nonce = header.getRecipNonce().getOctets();
    assertEquals(new String(nonce), new String(senderNonce));

    // --Transaction ID
    // transid should be the same as the one we sent
    nonce = header.getTransactionID().getOctets();
    assertEquals(new String(nonce), new String(transId));

}

From source file:org.ejbca.core.protocol.cmp.CrmfRequestMessage.java

License:Open Source License

private void init() {

    final PKIBody body = getPKIMessage().getBody();
    final PKIHeader header = getPKIMessage().getHeader();
    requestType = body.getType();/*from  w  ww  . j a va  2  s. c o  m*/
    final CertReqMessages msgs = getCertReqFromTag(body, requestType);

    try {
        this.req = msgs.toCertReqMsgArray()[0];
    } catch (Exception e) {
        this.req = CmpMessageHelper.getNovosecCertReqMsg(msgs);
    }

    requestId = this.req.getCertReq().getCertReqId().getValue().intValue();

    ASN1OctetString os = header.getTransactionID();
    if (os != null) {
        byte[] val = os.getOctets();
        if (val != null) {
            setTransactionId(new String(Base64.encode(val)));
        }
    }
    os = header.getSenderNonce();
    if (os != null) {
        byte[] val = os.getOctets();
        if (val != null) {
            setSenderNonce(new String(Base64.encode(val)));
        }
    }
    setRecipient(header.getRecipient());
    setSender(header.getSender());
}

From source file:org.ejbca.core.protocol.cmp.GeneralCmpMessage.java

License:Open Source License

public GeneralCmpMessage(final PKIMessage msg) {
    final PKIBody body = msg.getBody();
    final int tag = body.getType();
    if (tag == 19) {
        // this is a PKIConfirmContent
        if (log.isDebugEnabled()) {
            log.debug("Received a PKIConfirm message");
        }/*from www.  j  av a 2  s .  c  o m*/
        // This is a null message, so there is nothing to get here
        //DERNull obj = body.getConf();
    }
    if (tag == 24) {
        // this is a CertConfirmContent
        if (log.isDebugEnabled()) {
            log.debug("Received a Cert Confirm message");
        }
        final CertConfirmContent obj = (CertConfirmContent) body.getContent();
        CertStatus cs;
        try {
            cs = CertStatus.getInstance(obj.toASN1Primitive());
        } catch (Exception e) {
            cs = CertStatus.getInstance(((DERSequence) obj.toASN1Primitive()).getObjectAt(0));
        }
        final PKIStatusInfo status = cs.getStatusInfo();
        if (status != null) {
            final int st = status.getStatus().intValue();
            if (st != 0) {
                final String errMsg = intres.getLocalizedMessage("cmp.errorcertconfirmstatus",
                        Integer.valueOf(st));
                log.error(errMsg);
                // TODO: if it is rejected, we should revoke the cert?
            }
        }
    }
    if (tag == 11) {
        // this is a RevReqContent,
        if (log.isDebugEnabled()) {
            log.debug("Received a RevReqContent");
        }
        final RevReqContent rr = (RevReqContent) body.getContent();
        RevDetails rd;
        try {
            rd = rr.toRevDetailsArray()[0];
        } catch (Exception e) {
            log.debug(
                    "Could not parse the revocation request. Trying to parse it as novosec generated message.");
            rd = CmpMessageHelper.getNovosecRevDetails(rr);
            log.debug("Succeeded in parsing the novosec generated request.");
        }
        final CertTemplate ct = rd.getCertDetails();
        final ASN1Integer serno = ct.getSerialNumber();
        final X500Name issuer = ct.getIssuer();
        if ((serno != null) && (issuer != null)) {
            final String errMsg = intres.getLocalizedMessage("cmp.receivedrevreq", issuer.toString(),
                    serno.getValue().toString(16));
            log.info(errMsg);
        } else {
            final String errMsg = intres.getLocalizedMessage("cmp.receivedrevreqnoissuer");
            log.info(errMsg);
        }
    }
    setMessage(msg);
    final PKIHeader header = msg.getHeader();
    if (header.getTransactionID() != null) {
        final byte[] val = header.getTransactionID().getOctets();
        if (val != null) {
            setTransactionId(new String(Base64.encode(val)));
        }
    }
    if (header.getSenderNonce() != null) {
        final byte[] val = header.getSenderNonce().getOctets();
        if (val != null) {
            setSenderNonce(new String(Base64.encode(val)));
        }
    }
    setRecipient(header.getRecipient());
    setSender(header.getSender());
}

From source file:org.ejbca.core.protocol.cmp.NestedMessageContent.java

License:Open Source License

private void init() {
    final PKIHeader header = getPKIMessage().getHeader();
    ASN1OctetString os = header.getTransactionID();
    if (os != null) {
        final byte[] val = os.getOctets();
        if (val != null) {
            setTransactionId(new String(Base64.encode(val)));
        }/*from  w w w .  ja  v a  2  s  .  c  om*/
    }

    os = header.getSenderNonce();
    if (os != null) {
        final byte[] val = os.getOctets();
        if (val != null) {
            setSenderNonce(new String(Base64.encode(val)));
        }
    }
    setRecipient(header.getRecipient());
    setSender(header.getSender());
}

From source file:org.ejbca.ui.cmpclient.CmpClientMessageHelper.java

License:Open Source License

private PKIHeaderBuilder getHeaderBuilder(PKIHeader head) {
    PKIHeaderBuilder builder = new PKIHeaderBuilder(head.getPvno().getValue().intValue(), head.getSender(),
            head.getRecipient());/*  w  ww .j av a2  s. co m*/
    builder.setFreeText(head.getFreeText());
    builder.setGeneralInfo(head.getGeneralInfo());
    builder.setMessageTime(head.getMessageTime());
    builder.setRecipKID((DEROctetString) head.getRecipKID());
    builder.setRecipNonce(head.getRecipNonce());
    builder.setSenderKID(head.getSenderKID());
    builder.setSenderNonce(head.getSenderNonce());
    builder.setTransactionID(head.getTransactionID());
    return builder;
}

From source file:org.xipki.ca.client.impl.CmpRequestor.java

License:Open Source License

protected PKIResponse signAndSend(final PKIMessage request, final RequestResponseDebug debug)
        throws CmpRequestorException {
    PKIMessage _request;/*from   w ww.j  av  a  2  s  . co m*/
    if (signRequest) {
        _request = sign(request);
    } else {
        _request = request;
    }

    if (responderCert == null) {
        throw new CmpRequestorException("CMP responder is not configured");
    }

    byte[] encodedRequest;
    try {
        encodedRequest = _request.getEncoded();
    } catch (IOException e) {
        LOG.error("error while encode the PKI request {}", _request);
        throw new CmpRequestorException(e.getMessage(), e);
    }

    RequestResponsePair reqResp = null;
    if (debug != null) {
        reqResp = new RequestResponsePair();
        debug.add(reqResp);
        reqResp.setRequest(encodedRequest);
    }

    byte[] encodedResponse;
    try {
        encodedResponse = send(encodedRequest);
    } catch (IOException e) {
        LOG.error("error while send the PKI request {} to server", _request);
        throw new CmpRequestorException("TRANSPORT_ERROR", e);
    }

    if (reqResp != null) {
        reqResp.setResponse(encodedResponse);
    }

    GeneralPKIMessage response;
    try {
        response = new GeneralPKIMessage(encodedResponse);
    } catch (IOException e) {
        if (LOG.isErrorEnabled()) {
            LOG.error("error while decode the received PKI message: {}", Hex.toHexString(encodedResponse));
        }
        throw new CmpRequestorException(e.getMessage(), e);
    }

    PKIHeader respHeader = response.getHeader();
    ASN1OctetString tid = respHeader.getTransactionID();
    GeneralName recipient = respHeader.getRecipient();
    if (sender.equals(recipient) == false) {
        LOG.warn("tid={}: unknown CMP requestor '{}'", tid, recipient);
    }

    PKIResponse ret = new PKIResponse(response);
    if (response.hasProtection()) {
        try {
            ProtectionVerificationResult verifyProtection = verifyProtection(Hex.toHexString(tid.getOctets()),
                    response, responderCert);
            ret.setProtectionVerificationResult(verifyProtection);
        } catch (InvalidKeyException | OperatorCreationException | CMPException e) {
            throw new CmpRequestorException(e.getMessage(), e);
        }
    } else if (signRequest) {
        PKIBody respBody = response.getBody();
        int bodyType = respBody.getType();
        if (bodyType != PKIBody.TYPE_ERROR) {
            throw new CmpRequestorException("response is not signed");
        }
    }

    return ret;
}

From source file:org.xipki.ca.common.cmp.CmpUtil.java

License:Open Source License

public static PKIMessage addProtection(final PKIMessage pkiMessage, final ConcurrentContentSigner signer,
        GeneralName signerName, final boolean addSignerCert) throws CMPException, NoIdleSignerException {
    if (signerName == null) {
        X500Name x500Name = X500Name
                .getInstance(signer.getCertificate().getSubjectX500Principal().getEncoded());
        signerName = new GeneralName(x500Name);
    }/*from  w  ww.ja  va 2  s. co  m*/
    PKIHeader header = pkiMessage.getHeader();
    ProtectedPKIMessageBuilder builder = new ProtectedPKIMessageBuilder(signerName, header.getRecipient());
    PKIFreeText freeText = header.getFreeText();
    if (freeText != null) {
        builder.setFreeText(freeText);
    }

    InfoTypeAndValue[] generalInfo = header.getGeneralInfo();
    if (generalInfo != null) {
        for (InfoTypeAndValue gi : generalInfo) {
            builder.addGeneralInfo(gi);
        }
    }

    ASN1OctetString octet = header.getRecipKID();
    if (octet != null) {
        builder.setRecipKID(octet.getOctets());
    }

    octet = header.getRecipNonce();
    if (octet != null) {
        builder.setRecipNonce(octet.getOctets());
    }

    octet = header.getSenderKID();
    if (octet != null) {
        builder.setSenderKID(octet.getOctets());
    }

    octet = header.getSenderNonce();
    if (octet != null) {
        builder.setSenderNonce(octet.getOctets());
    }

    octet = header.getTransactionID();
    if (octet != null) {
        builder.setTransactionID(octet.getOctets());
    }

    if (header.getMessageTime() != null) {
        builder.setMessageTime(new Date());
    }
    builder.setBody(pkiMessage.getBody());

    if (addSignerCert) {
        X509CertificateHolder signerCert = signer.getCertificateAsBCObject();
        builder.addCMPCertificate(signerCert);
    }

    ContentSigner realSigner = signer.borrowContentSigner();
    try {
        ProtectedPKIMessage signedMessage = builder.build(realSigner);
        return signedMessage.toASN1Structure();
    } finally {
        signer.returnContentSigner(realSigner);
    }
}

From source file:org.xipki.ca.server.impl.CmpResponder.java

License:Open Source License

public PKIMessage processPKIMessage(final PKIMessage pkiMessage, final X509Certificate tlsClientCert,
        final AuditEvent auditEvent) throws ConfigurationException {
    GeneralPKIMessage message = new GeneralPKIMessage(pkiMessage);

    PKIHeader reqHeader = message.getHeader();
    ASN1OctetString tid = reqHeader.getTransactionID();

    if (tid == null) {
        byte[] randomBytes = randomTransactionId();
        tid = new DEROctetString(randomBytes);
    }/* w w  w  .  j a  v  a  2  s.com*/
    String tidStr = Hex.toHexString(tid.getOctets());
    if (auditEvent != null) {
        auditEvent.addEventData(new AuditEventData("tid", tidStr));
    }

    CmpControl cmpControl = getCmpControl();

    Integer failureCode = null;
    String statusText = null;

    Date messageTime = null;
    if (reqHeader.getMessageTime() != null) {
        try {
            messageTime = reqHeader.getMessageTime().getDate();
        } catch (ParseException e) {
            final String msg = "tid=" + tidStr + ": could not parse messageDate";
            if (LOG.isErrorEnabled()) {
                LOG.error(LogUtil.buildExceptionLogFormat(msg), e.getClass().getName(), e.getMessage());
            }
            LOG.debug(msg, e);
            messageTime = null;
        }
    }

    GeneralName recipient = reqHeader.getRecipient();
    boolean intentMe = (recipient == null) ? null : intendsMe(recipient);
    if (intentMe == false) {
        LOG.warn("tid={}: I am not the intented recipient, but '{}'", tid, reqHeader.getRecipient());
        failureCode = PKIFailureInfo.badRequest;
        statusText = "I am not the intended recipient";
    } else if (messageTime == null) {
        if (cmpControl.isMessageTimeRequired()) {
            failureCode = PKIFailureInfo.missingTimeStamp;
            statusText = "missing timestamp";
        }
    } else {
        long messageTimeBias = cmpControl.getMessageTimeBias();
        if (messageTimeBias < 0) {
            messageTimeBias *= -1;
        }

        long msgTimeMs = messageTime.getTime();
        long currentTimeMs = System.currentTimeMillis();
        long bias = (msgTimeMs - currentTimeMs) / 1000L;
        if (bias > messageTimeBias) {
            failureCode = PKIFailureInfo.badTime;
            statusText = "message time is in the future";
        } else if (bias * -1 > messageTimeBias) {
            failureCode = PKIFailureInfo.badTime;
            statusText = "message too old";
        }
    }

    if (failureCode != null) {
        if (auditEvent != null) {
            auditEvent.setLevel(AuditLevel.INFO);
            auditEvent.setStatus(AuditStatus.FAILED);
            auditEvent.addEventData(new AuditEventData("message", statusText));
        }
        return buildErrorPkiMessage(tid, reqHeader, failureCode, statusText);
    }

    boolean isProtected = message.hasProtection();
    CmpRequestorInfo requestor = null;

    String errorStatus;

    if (isProtected) {
        try {
            ProtectionVerificationResult verificationResult = verifyProtection(tidStr, message, cmpControl);
            ProtectionResult pr = verificationResult.getProtectionResult();
            switch (pr) {
            case VALID:
                errorStatus = null;
                break;
            case INVALID:
                errorStatus = "request is protected by signature but invalid";
                break;
            case NOT_SIGNATURE_BASED:
                errorStatus = "request is not protected by signature";
                break;
            case SENDER_NOT_AUTHORIZED:
                errorStatus = "request is protected by signature but the requestor is not authorized";
                break;
            case SIGALGO_FORBIDDEN:
                errorStatus = "request is protected by signature but the protection algorithm is forbidden";
                break;
            default:
                throw new RuntimeException("should not reach here, unknown ProtectionResult " + pr);
            } // end switch
            requestor = (CmpRequestorInfo) verificationResult.getRequestor();
        } catch (Exception e) {
            final String msg = "tid=" + tidStr + ": error while verifying the signature";
            if (LOG.isErrorEnabled()) {
                LOG.error(LogUtil.buildExceptionLogFormat(msg), e.getClass().getName(), e.getMessage());
            }
            LOG.debug(msg, e);
            errorStatus = "request has invalid signature based protection";
        }
    } else if (tlsClientCert != null) {
        boolean authorized = false;

        requestor = getRequestor(reqHeader);
        if (requestor != null) {
            if (tlsClientCert.equals(requestor.getCert().getCert())) {
                authorized = true;
            }
        }

        if (authorized) {
            errorStatus = null;
        } else {
            LOG.warn("tid={}: not authorized requestor (TLS client '{}')", tid,
                    X509Util.getRFC4519Name(tlsClientCert.getSubjectX500Principal()));
            errorStatus = "requestor (TLS client certificate) is not authorized";
        }
    } else {
        errorStatus = "request has no protection";
        requestor = null;
    }

    CmpUtf8Pairs keyvalues = CmpUtil.extract(reqHeader.getGeneralInfo());
    String username = keyvalues == null ? null : keyvalues.getValue(CmpUtf8Pairs.KEY_USER);
    if (username != null) {
        if (username.indexOf('*') != -1 || username.indexOf('%') != -1) {
            errorStatus = "user could not contains characters '*' and '%'";
        }
    }

    if (errorStatus != null) {
        if (auditEvent != null) {
            auditEvent.setLevel(AuditLevel.INFO);
            auditEvent.setStatus(AuditStatus.FAILED);
            auditEvent.addEventData(new AuditEventData("message", errorStatus));
        }
        return buildErrorPkiMessage(tid, reqHeader, PKIFailureInfo.badMessageCheck, errorStatus);
    }

    PKIMessage resp = intern_processPKIMessage(requestor, username, tid, message, auditEvent);

    if (isProtected) {
        resp = addProtection(resp, auditEvent);
    } else {
        // protected by TLS connection
    }

    return resp;
}