Example usage for org.bouncycastle.cert.cmp GeneralPKIMessage GeneralPKIMessage

List of usage examples for org.bouncycastle.cert.cmp GeneralPKIMessage GeneralPKIMessage

Introduction

In this page you can find the example usage for org.bouncycastle.cert.cmp GeneralPKIMessage GeneralPKIMessage.

Prototype

public GeneralPKIMessage(PKIMessage pkiMessage) 

Source Link

Document

Wrap a PKIMessage ASN.1 structure.

Usage

From source file:org.cryptable.pki.communication.PKICMPMessages.java

License:Open Source License

/**
 * The message to decode a certification response
 *
 * @param message//from w  ww.  j a  v  a2  s  . c o m
 * @return response message
 * @throws IOException
 * @throws PKICMPMessageException
 */
PKICMPResponse processResponse(byte[] message) throws IOException, PKICMPMessageException, CertificateException,
        OperatorCreationException, CMPException, PKIKeyStoreException, ParseException {
    CertificationResult certificationResult = new CertificationResult();

    ProtectedPKIMessage pkiMessage = new ProtectedPKIMessage(new GeneralPKIMessage(message));

    /* Verify Signature */
    ContentVerifierProvider verifierProvider = new JcaContentVerifierProviderBuilder()
            .setProvider(pkiKeyStore.getProvider()).build(pkiKeyStore.getRecipientCertificate());

    if (!pkiMessage.verify(verifierProvider)) {
        throw new PKICMPMessageException("E: Verification failed this is an untrusted Message ["
                + pkiMessage.getHeader().getSender() + "]");
    }

    if (!Arrays.equals(senderNonce, pkiMessage.getHeader().getRecipNonce().getOctets()))
        throw new PKICMPMessageException(
                "E: Recipient Nonce in response does not correspond with Sender Nonce in request!");
    if (pkiMessage.getHeader().getMessageTime() != null) {
        pkiKeyStore.verifyCertificate(pkiKeyStore.getRecipientCertificate(),
                pkiMessage.getHeader().getMessageTime().getDate());
    } else {
        pkiKeyStore.verifyCertificate(pkiKeyStore.getRecipientCertificate(), new Date());
    }
    PKICMPResponse pkicmpResponse = new PKICMPResponse();

    pkicmpResponse.setPkiBody(pkiMessage.getBody());
    pkicmpResponse.setPkiHeader(pkiMessage.getHeader());

    X509CertificateHolder[] x509CertificateHolders = pkiMessage.getCertificates();
    JcaX509CertificateConverter jcaX509CertificateConverter = new JcaX509CertificateConverter();
    for (X509CertificateHolder x509CertificateHolder : x509CertificateHolders) {
        pkicmpResponse.getX509CertifificateList()
                .add(jcaX509CertificateConverter.getCertificate(x509CertificateHolder));

    }
    return pkicmpResponse;
}

From source file:org.cryptable.pki.communication.PKICMPMessagesTest.java

License:Open Source License

/**
 * Test the basic certification request message
 *
 * @throws OperatorCreationException//  w w  w .  j av  a  2s.c om
 * @throws CertificateEncodingException
 * @throws IOException
 * @throws CRMFException
 * @throws CMPException
 * @throws CMSException
 */
@Test
public void testCertification() throws OperatorCreationException, CertificateEncodingException, IOException,
        CRMFException, CMPException, CMSException, ParseException, PKICMPMessageException,
        NoSuchProviderException, NoSuchAlgorithmException, NoSuchFieldException, IllegalAccessException {
    String distinguishedName = pki.getTestUser1Cert().getSubjectX500Principal().getName();

    KeyPair keyPair = new KeyPair(pki.getTestUser1Cert().getPublicKey(), pki.getTestUser1CertPrivateKey());

    PKICMPMessages pkiMessages = new PKICMPMessages();
    pkiMessages.setPkiKeyStore(pkiKeyStoreRA);
    byte[] result = pkiMessages.createCertificateMessageWithLocalKey(distinguishedName, keyPair);

    ASN1InputStream asn1InputStream = new ASN1InputStream(result);
    ASN1Primitive asn1Primitive = asn1InputStream.readObject();
    PKIMessage pkiMessage = PKIMessage.getInstance(asn1Primitive);

    // Header verification
    Assert.assertEquals(pkiMessage.getHeader().getPvno().getValue(), BigInteger.valueOf(2));
    Assert.assertEquals(pkiKeyStoreRA.getRecipientCertificate().getSubjectDN().getName(),
            pkiMessage.getHeader().getRecipient().getName().toString());
    Assert.assertEquals(pkiKeyStoreRA.getSenderCertificate().getSubjectDN().getName(),
            pkiMessage.getHeader().getSender().getName().toString());
    Assert.assertNotNull(pkiMessage.getHeader().getSenderNonce());
    Assert.assertNotNull(pkiMessage.getHeader().getTransactionID());
    Assert.assertNotNull(pkiMessage.getHeader().getMessageTime().getDate());
    // check the body
    // Check the tests in Bouncycastle for decoding cert request
    Assert.assertEquals(PKIBody.TYPE_CERT_REQ, pkiMessage.getBody().getType());
    CertReqMsg[] certReqMsgs = CertReqMessages.getInstance(pkiMessage.getBody().getContent())
            .toCertReqMsgArray();
    Assert.assertEquals(BigInteger.ZERO.toString(), certReqMsgs[0].getCertReq().getCertReqId().toString());
    Assert.assertEquals(distinguishedName,
            certReqMsgs[0].getCertReq().getCertTemplate().getSubject().toString());
    Assert.assertArrayEquals(keyPair.getPublic().getEncoded(),
            certReqMsgs[0].getCertReq().getCertTemplate().getPublicKey().getEncoded());
    AttributeTypeAndValue[] attributeTypeAndValue = certReqMsgs[0].getCertReq().getControls()
            .toAttributeTypeAndValueArray();
    Assert.assertEquals(CRMFObjectIdentifiers.id_regCtrl_pkiArchiveOptions, attributeTypeAndValue[0].getType());
    // Check the signature
    GeneralPKIMessage generalPKIMessage = new GeneralPKIMessage(result);
    Assert.assertTrue(generalPKIMessage.hasProtection());
    ProtectedPKIMessage pkiMsg = new ProtectedPKIMessage(generalPKIMessage);
    ContentVerifierProvider verifierProvider = new JcaContentVerifierProviderBuilder()
            .setProvider(pkiKeyStoreRA.getProvider())
            .build(pkiKeyStoreRA.getSenderCertificate().getPublicKey());

    Assert.assertTrue(pkiMsg.verify(verifierProvider));
}

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 ww w.ja v a  2 s  .  c  om
    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.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);
    }//from  w  w  w  .j  a  v a2  s .c  o m
    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;
}

From source file:org.xipki.commons.remotep11.server.CmpResponder.java

License:Open Source License

PKIMessage processPkiMessage(final LocalP11CryptServicePool p11CryptServicePool, final String moduleName,
        final PKIMessage pkiMessage) {
    ParamUtil.requireNonNull("p11CryptServicePool", p11CryptServicePool);
    ParamUtil.requireNonNull("pkiMessage", pkiMessage);
    GeneralPKIMessage message = new GeneralPKIMessage(pkiMessage);

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

    if (tid == null) {
        byte[] randomBytes = randomTransactionId();
        tid = new DEROctetString(randomBytes);
    }//from  ww  w  .  jav  a2 s .c om
    String tidStr = Hex.toHexString(tid.getOctets());

    PKIHeaderBuilder respHeaderBuilder = new PKIHeaderBuilder(reqHeader.getPvno().getValue().intValue(), sender,
            reqHeader.getSender());
    respHeaderBuilder.setTransactionID(tid);

    PKIBody reqBody = message.getBody();
    final int type = reqBody.getType();

    PKIHeader respHeader = respHeaderBuilder.build();

    if (type != PKIBody.TYPE_GEN_MSG) {
        ErrorMsgContent emc = new ErrorMsgContent(new PKIStatusInfo(PKIStatus.rejection,
                new PKIFreeText("unsupported type " + type), new PKIFailureInfo(PKIFailureInfo.badRequest)));

        PKIBody respBody = new PKIBody(PKIBody.TYPE_ERROR, emc);
        return new PKIMessage(respHeader, respBody);
    }

    GenMsgContent genMsgBody = GenMsgContent.getInstance(reqBody.getContent());
    InfoTypeAndValue[] itvs = genMsgBody.toInfoTypeAndValueArray();

    InfoTypeAndValue itv = null;
    if (itvs != null && itvs.length > 0) {
        for (InfoTypeAndValue m : itvs) {
            ASN1ObjectIdentifier itvType = m.getInfoType();
            if (ObjectIdentifiers.id_xipki_cmp_cmpGenmsg.equals(itvType)) {
                itv = m;
                break;
            }
        }
    }

    if (itv == null) {
        final String statusMessage = String.format("PKIBody type %s is only supported with the sub-knownTypes",
                ObjectIdentifiers.id_xipki_cmp_cmpGenmsg.getId());
        return createRejectionPkiMessage(respHeader, PKIFailureInfo.badRequest, statusMessage);
    }

    try {
        return doProcessPkiMessage(p11CryptServicePool, moduleName, itv, respHeader);
    } catch (BadAsn1ObjectException ex) {
        LogUtil.error(LOG, ex, "could not process CMP message " + tidStr);
        return createRejectionPkiMessage(respHeader, PKIFailureInfo.badRequest, ex.getMessage());
    } catch (P11TokenException ex) {
        LogUtil.error(LOG, ex, "could not process CMP message " + tidStr);

        String p11ErrorType;
        if (ex instanceof P11UnknownEntityException) {
            p11ErrorType = P11ProxyConstants.ERROR_UNKNOWN_ENTITY;
        } else if (ex instanceof P11DuplicateEntityException) {
            p11ErrorType = P11ProxyConstants.ERROR_DUPLICATE_ENTITY;
        } else if (ex instanceof P11UnsupportedMechanismException) {
            p11ErrorType = P11ProxyConstants.ERROR_UNSUPPORTED_MECHANISM;
        } else {
            p11ErrorType = P11ProxyConstants.ERROR_P11_TOKENERROR;
        }

        String errorMessage = ex.getMessage();

        if (errorMessage == null) {
            errorMessage = "NULL";
        } else if (StringUtil.isBlank(errorMessage.trim())) {
            errorMessage = "NULL";
        }

        ConfPairs confPairs = new ConfPairs(p11ErrorType, errorMessage);
        return createRejectionPkiMessage(respHeader, PKIFailureInfo.badRequest, confPairs.getEncoded());
    } catch (Throwable th) {
        LogUtil.error(LOG, th, "could not process CMP message " + tidStr);
        return createRejectionPkiMessage(respHeader, PKIFailureInfo.systemFailure, "SYSTEM_FAILURE");
    }
}

From source file:org.xipki.commons.security.pkcs11.proxy.ProxyP11Module.java

License:Open Source License

ASN1Encodable send(final int action, final ASN1Encodable content) throws P11TokenException {
    ASN1EncodableVector vec = new ASN1EncodableVector();
    vec.add(new ASN1Integer(version));
    vec.add(new ASN1Integer(action));
    vec.add((content != null) ? content : DERNull.INSTANCE);
    InfoTypeAndValue itvReq = new InfoTypeAndValue(ObjectIdentifiers.id_xipki_cmp_cmpGenmsg,
            new DERSequence(vec));

    GenMsgContent genMsgContent = new GenMsgContent(itvReq);
    PKIHeader header = buildPkiHeader(null);
    PKIBody body = new PKIBody(PKIBody.TYPE_GEN_MSG, genMsgContent);
    PKIMessage request = new PKIMessage(header, body);

    byte[] encodedRequest;
    try {//from  w  w  w.  jav a  2 s  .c  om
        encodedRequest = request.getEncoded();
    } catch (IOException ex) {
        final String msg = "could not encode the PKI request";
        LOG.error(msg + " {}", request);
        throw new P11TokenException(msg + ": " + ex.getMessage(), ex);
    }

    byte[] encodedResponse;
    try {
        encodedResponse = send(encodedRequest);
    } catch (IOException ex) {
        final String msg = "could not send the PKI request";
        LOG.error(msg + " {}", request);
        throw new P11TokenException(msg + ": " + ex.getMessage(), ex);
    }

    GeneralPKIMessage response;
    try {
        response = new GeneralPKIMessage(encodedResponse);
    } catch (IOException ex) {
        final String msg = "could not decode the received PKI message";
        LOG.error(msg + ": {}", Hex.toHexString(encodedResponse));
        throw new P11TokenException(msg + ": " + ex.getMessage(), ex);
    }

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

    return extractItvInfoValue(action, response);
}

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

License:Open Source License

protected PkiResponse signAndSend(final PKIMessage request, final RequestResponseDebug debug)
        throws CmpRequestorException {
    ParamUtil.requireNonNull("request", request);

    PKIMessage tmpRequest = (signRequest) ? sign(request) : request;

    byte[] encodedRequest;
    try {/*from   w  w  w.  ja  va  2  s .com*/
        encodedRequest = tmpRequest.getEncoded();
    } catch (IOException ex) {
        LOG.error("could not encode the PKI request {}", tmpRequest);
        throw new CmpRequestorException(ex.getMessage(), ex);
    }

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

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

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

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

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

    PkiResponse ret = new PkiResponse(response);
    if (response.hasProtection()) {
        try {
            ProtectionVerificationResult verifyProtection = verifyProtection(Hex.toHexString(tid.getOctets()),
                    response);
            ret.setProtectionVerificationResult(verifyProtection);
        } catch (InvalidKeyException | OperatorCreationException | CMPException ex) {
            throw new CmpRequestorException(ex.getMessage(), ex);
        }
    } 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.pki.ca.server.impl.cmp.CmpResponder.java

License:Open Source License

public PKIMessage processPkiMessage(final PKIMessage pkiMessage, final X509Certificate tlsClientCert,
        final String tidStr, final AuditEvent event) {
    ParamUtil.requireNonNull("pkiMessage", pkiMessage);
    ParamUtil.requireNonNull("event", event);
    GeneralPKIMessage message = new GeneralPKIMessage(pkiMessage);

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

    String msgId = null;//from   w ww .ja  v  a  2  s . co m
    if (event != null) {
        msgId = RandomUtil.nextHexLong();
        event.addEventData(CaAuditConstants.NAME_mid, msgId);
    }

    if (tid == null) {
        byte[] randomBytes = randomTransactionId();
        tid = new DEROctetString(randomBytes);
    }

    CmpControl cmpControl = getCmpControl();

    Integer failureCode = null;
    String statusText = null;

    Date messageTime = null;
    if (reqHeader.getMessageTime() != null) {
        try {
            messageTime = reqHeader.getMessageTime().getDate();
        } catch (ParseException ex) {
            LogUtil.error(LOG, ex, "tid=" + tidStr + ": could not parse messageDate");
        }
    }

    GeneralName recipient = reqHeader.getRecipient();
    boolean intentMe = (recipient == null) ? true : intendsMe(recipient);
    if (!intentMe) {
        LOG.warn("tid={}: I am not the intended 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 time-stamp";
        }
    } 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 (event != null) {
            event.setLevel(AuditLevel.INFO);
            event.setStatus(AuditStatus.FAILED);
            event.addEventData(CaAuditConstants.NAME_message, statusText);
        }
        return buildErrorPkiMessage(tid, reqHeader, failureCode, statusText);
    }

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

    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 ex) {
            LogUtil.error(LOG, ex, "tid=" + tidStr + ": could not verify the signature");
            errorStatus = "request has invalid signature based protection";
            requestor = null;
        }
    } 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 (event != null) {
            event.setLevel(AuditLevel.INFO);
            event.setStatus(AuditStatus.FAILED);
            event.addEventData(CaAuditConstants.NAME_message, errorStatus);
        }
        return buildErrorPkiMessage(tid, reqHeader, PKIFailureInfo.badMessageCheck, errorStatus);
    }

    PKIMessage resp = doProcessPkiMessage(pkiMessage, requestor, username, tid, message, msgId, event);

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

    return resp;
}

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

License:Open Source License

PKIMessage processPKIMessage(final LocalP11CryptServicePool localP11CryptServicePool, final String moduleName,
        final PKIMessage pkiMessage) {
    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  av  a 2s  .c o m*/
    String tidStr = Hex.toHexString(tid.getOctets());

    PKIHeaderBuilder respHeaderBuilder = new PKIHeaderBuilder(reqHeader.getPvno().getValue().intValue(), sender,
            reqHeader.getSender());
    respHeaderBuilder.setTransactionID(tid);

    PKIBody reqBody = message.getBody();
    final int type = reqBody.getType();

    PKIHeader respHeader = respHeaderBuilder.build();

    if (type != PKIBody.TYPE_GEN_MSG) {
        ErrorMsgContent emc = new ErrorMsgContent(new PKIStatusInfo(PKIStatus.rejection,
                new PKIFreeText("unsupported type " + type), new PKIFailureInfo(PKIFailureInfo.badRequest)));

        PKIBody respBody = new PKIBody(PKIBody.TYPE_ERROR, emc);

        return new PKIMessage(respHeader, respBody);
    }

    GenMsgContent genMsgBody = (GenMsgContent) reqBody.getContent();
    InfoTypeAndValue[] itvs = genMsgBody.toInfoTypeAndValueArray();

    InfoTypeAndValue itv = null;
    if (itvs != null && itvs.length > 0) {
        for (InfoTypeAndValue m : itvs) {
            ASN1ObjectIdentifier itvType = m.getInfoType();
            if (ObjectIdentifiers.id_xipki_cmp.equals(itvType)) {
                itv = m;
                break;
            }
        }
    }

    if (itv == null) {
        final String statusMessage = String.format("PKIBody type %s is only supported with the sub-knownTypes",
                ObjectIdentifiers.id_xipki_cmp.getId());
        return createRejectionPKIMessage(respHeader, PKIFailureInfo.badRequest, statusMessage);
    }

    try {
        ASN1Encodable asn1 = itv.getInfoValue();
        ASN1Integer asn1Code = null;
        ASN1Encodable reqValue = null;

        try {
            ASN1Sequence seq = ASN1Sequence.getInstance(asn1);
            asn1Code = ASN1Integer.getInstance(seq.getObjectAt(0));
            if (seq.size() > 1) {
                reqValue = seq.getObjectAt(1);
            }
        } catch (IllegalArgumentException e) {
            final String statusMessage = "invalid value of the InfoTypeAndValue for "
                    + ObjectIdentifiers.id_xipki_cmp.getId();
            return createRejectionPKIMessage(respHeader, PKIFailureInfo.badRequest, statusMessage);
        }

        int action = asn1Code.getPositiveValue().intValue();
        ASN1Encodable respItvInfoValue;

        P11CryptService p11CryptService = localP11CryptServicePool.getP11CryptService(moduleName);

        switch (action) {
        case XipkiCmpConstants.ACTION_RP11_VERSION: {
            respItvInfoValue = new ASN1Integer(localP11CryptServicePool.getVersion());
            break;
        }
        case XipkiCmpConstants.ACTION_RP11_PSO_DSA_PLAIN:
        case XipkiCmpConstants.ACTION_RP11_PSO_DSA_X962:
        case XipkiCmpConstants.ACTION_RP11_PSO_ECDSA_PLAIN:
        case XipkiCmpConstants.ACTION_RP11_PSO_ECDSA_X962:
        case XipkiCmpConstants.ACTION_RP11_PSO_RSA_PKCS:
        case XipkiCmpConstants.ACTION_RP11_PSO_RSA_X509: {
            byte[] psoMessage = null;
            P11SlotIdentifier slot = null;
            P11KeyIdentifier keyId = null;
            {
                try {
                    PSOTemplate psoTemplate = PSOTemplate.getInstance(reqValue);
                    psoMessage = psoTemplate.getMessage();
                    SlotAndKeyIdentifer slotAndKeyIdentifier = psoTemplate.getSlotAndKeyIdentifer();
                    slot = slotAndKeyIdentifier.getSlotIdentifier().getSlotId();
                    KeyIdentifier keyIdentifier = slotAndKeyIdentifier.getKeyIdentifier();
                    keyId = keyIdentifier.getKeyId();
                } catch (IllegalArgumentException e) {
                    final String statusMessage = "invalid PSOTemplate";
                    return createRejectionPKIMessage(respHeader, PKIFailureInfo.badRequest, statusMessage);
                }
            }

            byte[] signature;

            if (XipkiCmpConstants.ACTION_RP11_PSO_ECDSA_PLAIN == action) {
                signature = p11CryptService.CKM_ECDSA_Plain(psoMessage, slot, keyId);
            } else if (XipkiCmpConstants.ACTION_RP11_PSO_ECDSA_X962 == action) {
                signature = p11CryptService.CKM_ECDSA_X962(psoMessage, slot, keyId);
            } else if (XipkiCmpConstants.ACTION_RP11_PSO_DSA_PLAIN == action) {
                signature = p11CryptService.CKM_DSA_Plain(psoMessage, slot, keyId);
            } else if (XipkiCmpConstants.ACTION_RP11_PSO_DSA_X962 == action) {
                signature = p11CryptService.CKM_DSA_X962(psoMessage, slot, keyId);
            } else if (XipkiCmpConstants.ACTION_RP11_PSO_RSA_X509 == action) {
                signature = p11CryptService.CKM_RSA_X509(psoMessage, slot, keyId);
            } else if (XipkiCmpConstants.ACTION_RP11_PSO_RSA_PKCS == action) {
                signature = p11CryptService.CKM_RSA_PKCS(psoMessage, slot, keyId);
            } else {
                throw new RuntimeException("should not reach here");
            }

            respItvInfoValue = new DEROctetString(signature);
            break;
        }
        case XipkiCmpConstants.ACTION_RP11_GET_CERTIFICATE:
        case XipkiCmpConstants.ACTION_RP11_GET_PUBLICKEY: {
            P11SlotIdentifier slot = null;
            P11KeyIdentifier keyId = null;
            try {
                SlotAndKeyIdentifer slotAndKeyIdentifier = SlotAndKeyIdentifer.getInstance(reqValue);
                slot = slotAndKeyIdentifier.getSlotIdentifier().getSlotId();
                KeyIdentifier keyIdentifier = slotAndKeyIdentifier.getKeyIdentifier();
                keyId = keyIdentifier.getKeyId();
            } catch (IllegalArgumentException e) {
                final String statusMessage = "invalid SlotAndKeyIdentifier";
                return createRejectionPKIMessage(respHeader, PKIFailureInfo.badRequest, statusMessage);
            }

            byte[] encodeCertOrKey;
            if (XipkiCmpConstants.ACTION_RP11_GET_CERTIFICATE == action) {
                encodeCertOrKey = p11CryptService.getCertificate(slot, keyId).getEncoded();
            } else if (XipkiCmpConstants.ACTION_RP11_GET_PUBLICKEY == action) {
                encodeCertOrKey = p11CryptService.getPublicKey(slot, keyId).getEncoded();
            } else {
                throw new RuntimeException("should not reach here");
            }

            respItvInfoValue = new DEROctetString(encodeCertOrKey);
            break;
        }
        case XipkiCmpConstants.ACTION_RP11_LIST_SLOTS: {
            P11SlotIdentifier[] slotIds = p11CryptService.getSlotIdentifiers();

            ASN1EncodableVector vector = new ASN1EncodableVector();
            for (P11SlotIdentifier slotId : slotIds) {
                vector.add(new SlotIdentifier(slotId));
            }
            respItvInfoValue = new DERSequence(vector);
            break;
        }
        case XipkiCmpConstants.ACTION_RP11_LIST_KEYLABELS: {
            SlotIdentifier slotId = SlotIdentifier.getInstance(reqValue);
            String[] keyLabels = p11CryptService.getKeyLabels(slotId.getSlotId());

            ASN1EncodableVector vector = new ASN1EncodableVector();
            for (String keyLabel : keyLabels) {
                vector.add(new DERUTF8String(keyLabel));
            }
            respItvInfoValue = new DERSequence(vector);
            break;
        }
        default: {
            final String statusMessage = "unsupported XiPKI action code '" + action + "'";
            return createRejectionPKIMessage(respHeader, PKIFailureInfo.badRequest, statusMessage);
        }
        } // end switch(code)

        ASN1EncodableVector v = new ASN1EncodableVector();
        v.add(new ASN1Integer(action));
        if (respItvInfoValue != null) {
            v.add(respItvInfoValue);
        }
        InfoTypeAndValue respItv = new InfoTypeAndValue(ObjectIdentifiers.id_xipki_cmp, new DERSequence(v));
        GenRepContent genRepContent = new GenRepContent(respItv);
        PKIBody respBody = new PKIBody(PKIBody.TYPE_GEN_REP, genRepContent);
        return new PKIMessage(respHeader, respBody);
    } catch (Throwable t) {
        LOG.error("error while processing CMP message {}, message: {}", tidStr, t.getMessage());
        LOG.debug("error while processing CMP message " + tidStr, t);
        return createRejectionPKIMessage(respHeader, PKIFailureInfo.systemFailure, t.getMessage());
    }
}

From source file:org.xipki.security.p11.remote.RemoteP11CryptService.java

License:Open Source License

private ASN1Encodable send(final int action, final ASN1Encodable content) throws SignerException {
    PKIHeader header = buildPKIHeader(null);
    ASN1EncodableVector v = new ASN1EncodableVector();
    v.add(new ASN1Integer(action));
    if (content != null) {
        v.add(content);//from ww w . j  a v a 2  s.  co  m
    }
    InfoTypeAndValue itvReq = new InfoTypeAndValue(ObjectIdentifiers.id_xipki_cmp, new DERSequence(v));

    GenMsgContent genMsgContent = new GenMsgContent(itvReq);
    PKIBody body = new PKIBody(PKIBody.TYPE_GEN_MSG, genMsgContent);
    PKIMessage request = new PKIMessage(header, body);

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

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

    GeneralPKIMessage response;
    try {
        response = new GeneralPKIMessage(encodedResponse);
    } catch (IOException e) {
        LOG.error("error while decode the received PKI message: {}", Hex.toHexString(encodedResponse));
        throw new SignerException(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);
    }

    return extractItvInfoValue(action, response);
}