Example usage for org.bouncycastle.asn1 ASN1InputStream readObject

List of usage examples for org.bouncycastle.asn1 ASN1InputStream readObject

Introduction

In this page you can find the example usage for org.bouncycastle.asn1 ASN1InputStream readObject.

Prototype

public ASN1Primitive readObject() throws IOException 

Source Link

Usage

From source file:org.ejbca.core.protocol.ws.CommonEjbcaWS.java

License:Open Source License

private CertReqMsg createCrmfRequest(final String issuerDN, final String userDN, final KeyPair keys,
        final String extensionOid) throws IOException {
    CertTemplateBuilder myCertTemplate = new CertTemplateBuilder();
    myCertTemplate.setIssuer(new X500Name(issuerDN));
    myCertTemplate.setSubject(new X500Name(userDN));
    byte[] bytes = keys.getPublic().getEncoded();
    ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);
    ASN1InputStream dIn = new ASN1InputStream(bIn);
    try {//  w  w w .  j av a2  s  . co  m
        SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo((ASN1Sequence) dIn.readObject());
        myCertTemplate.setPublicKey(keyInfo);
    } finally {
        dIn.close();
    }
    // If we did not pass any extensions as parameter, we will create some of our own, standard ones
    ExtensionsGenerator extgen = new ExtensionsGenerator();
    extgen.addExtension(new ASN1ObjectIdentifier(extensionOid), false, new DEROctetString("foo123".getBytes()));
    myCertTemplate.setExtensions(extgen.generate());
    CertRequest myCertRequest = new CertRequest(4, myCertTemplate.build(), null);
    CertReqMsg myCertReqMsg = new CertReqMsg(myCertRequest, null, null);
    return myCertReqMsg;
}

From source file:org.ejbca.externalra.gui.EnrollInterfaceBean.java

License:Open Source License

/**
 * Action that requests a certificate from EJBCA using the given credentials and the Certificate Signing Request created by the browser.
 *//*from   ww  w . jav  a 2  s .  co  m*/
public void createCertFromBrowser() {
    log.info("Recieved a browser generated certificate request of type " + certificateRequestType
            + " for username '" + username + "' from " + getRemoteAddress());
    if (log.isDebugEnabled()) {
        log.debug("certificateRequest: " + certificateRequest);
    }
    FacesContext context = FacesContext.getCurrentInstance();
    if (username == null || username.length() == 0 || password == null || password.length() == 0
            || certificateRequest == null || certificateRequest.length() == 0 || certificateRequestType == null
            || certificateRequestType.length() == 0) {
        context.addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, getMessage("enroll.incompletefields"), null));
        return;
    }
    // Verify that we got a valid certificate request and determine response type
    byte[] buf = null;
    int requestType = Integer.parseInt(certificateRequestType);
    int responseType;
    switch (requestType) {
    case CertificateRequestRequest.REQUEST_TYPE_CRMF:
        responseType = CertificateRequestRequest.RESPONSE_TYPE_PKCS7;
        buf = Base64.decode(certificateRequest.getBytes());
        ASN1InputStream asn1InputStream = new ASN1InputStream(buf);
        try {
            // Verify that we can parse this as a CRMF object
            CertReqMessages.getInstance(asn1InputStream.readObject()).getCertReqMsg(0);
        } catch (IOException e) {
            context.addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, getMessage("enroll.invalidreqdata"), null));
            log.error("", e);
        }
        break;
    case CertificateRequestRequest.REQUEST_TYPE_PKCS10:
        responseType = CertificateRequestRequest.RESPONSE_TYPE_PKCS7;
        try {
            if (!isWindowsNT5()) {
                responseType = CertificateRequestRequest.RESPONSE_TYPE_UNSIGNEDPKCS7;
            }
            // Replace Vista PEM markers
            certificateRequest = certificateRequest.replaceAll(PEM_CSR_BEGIN_VISTA, PEM_CSR_BEGIN);
            certificateRequest = certificateRequest.replaceAll(PEM_CSR_END_VISTA, PEM_CSR_END);
            if (certificateRequest.indexOf(PEM_CSR_BEGIN) == -1) {
                certificateRequest = PEM_CSR_BEGIN + "\n" + certificateRequest + "\n" + PEM_CSR_END;
            }
            buf = FileTools.getBytesFromPEM(certificateRequest.getBytes(), PEM_CSR_BEGIN, PEM_CSR_END);
            new PKCS10CertificationRequest(buf);
        } catch (Exception e) {
            log.error("", e);
            context.addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, getMessage("enroll.invalidreqdata"), null));
            return;
        }
        break;
    case CertificateRequestRequest.REQUEST_TYPE_KEYGEN:
        responseType = CertificateRequestRequest.RESPONSE_TYPE_PKCS7;
        try {
            buf = Base64.decode(certificateRequest.getBytes());
            ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(buf));
            ASN1Sequence spkac = (ASN1Sequence) in.readObject();
            in.close();
            NetscapeCertRequest nscr = new NetscapeCertRequest(spkac);
            // Verify POPO, we don't care about the challenge, it's not important.
            nscr.setChallenge("challenge");
            if (nscr.verify("challenge") == false) {
                context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
                        getMessage("enroll.invalidreqdata"), null));
                return;
            }
        } catch (Exception e) {
            log.error("", e);
            context.addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, getMessage("enroll.invalidreqdata"), null));
            return;
        }
        break;
    case -1:
        // This is a workaround to hide errors when we use the KeyGenServlet..
        return;
    default:
        context.addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, getMessage("enroll.unknownrequesttype"), null));
        return;
    }
    // Request the certificate from the CA
    if (log.isDebugEnabled()) {
        log.debug("Got requestType " + requestType + " and is expecting responseType " + responseType
                + " for user " + username);
    }
    ResponseData responseData = getRequestDispatcher().getCertificateResponse(username, password, requestType,
            buf, responseType);
    // Check if got a valid result
    if (responseData == null) {
        context.addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, getMessage("enroll.noresponse"), null));
        log.error("Certificate request for '" + username + "' failed. No response from CA.");
        return;
    } else if (responseData.getErrorMessage() != null) {
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
                getMessage("enroll.browsercert.couldnotcreate"), null));
        log.info("Certificate request for '" + username + "' failed. " + responseData.getErrorMessage());
        return;
    }
    // Handle response
    certificateResponseType = "" + responseData.getResponseType();
    switch (responseData.getResponseType()) {
    case CertificateRequestRequest.RESPONSE_TYPE_PKCS7:
        if (isInternetExplorer()) {
            // Working for XP+IE7
            certificateResponse = new String(Base64.encode(responseData.getResponseData(), false));
        } else {
            resource = new ByteArrayResource(responseData.getResponseData());
            mimeType = "application/x-x509-user-cert";
        }
        break;
    case CertificateRequestRequest.RESPONSE_TYPE_UNSIGNEDPKCS7:
        // Working for Vista+IE8
        certificateResponse = new String(Base64.encode(responseData.getResponseData(), false));
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            String pkcs7 = PEM_PKCS7_BEGIN + "\n"
                    + new String(Base64.encode(responseData.getResponseData(), true)) + "\n" + PEM_PKCS7_END
                    + "\n";
            log.debug("pkcs7=" + pkcs7);
            CertPath certPath = cf.generateCertPath(new ByteArrayInputStream(responseData.getResponseData()),
                    "PKCS7");
            List<? extends Certificate> certList = certPath.getCertificates();
            Certificate caCert = certList.get(certList.size() - 1);
            String caCertificate = new String(Base64.encode(caCert.getEncoded(), false));
            resource = new ByteArrayResource(caCertificate.getBytes());
            mimeType = "application/x-x509-ca-cert";
        } catch (CertificateException e) {
            e.printStackTrace();
        }
        if (log.isDebugEnabled()) {
            log.debug("certificateResponse: " + certificateResponse);
        }
        break;
    default:
        context.addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, getMessage("enroll.unknownresponsetype"), null));
        log.error("Unknown result type: " + certificateResponseType);
        break;
    }
    log.info("Certificate request with response-type " + responseData.getResponseType() + " for '" + username
            + "' was successful.");
}

From source file:org.ejbca.extra.caservice.processor.CertificateRequestRequestProcessor.java

License:Open Source License

/**
 * Extracts the certificate signing request type and requests a new certificate using the provided credentials.
 *///from w ww  .ja  va  2  s.c o  m
private CertificateRequestResponse processCertificateRequestRequest(Admin admin,
        CertificateRequestRequest submessage) {
    if (log.isDebugEnabled()) {
        log.debug("Processing CertificateRequestRequest");
    }
    try {
        byte[] result = null;
        if (submessage.createOrEditUser()) {
            if (log.isDebugEnabled()) {
                log.debug("createOrEditUser == true, will use one-shot request processing.");
            }
            final UserDataVO userdatavo = getUserDataVO(admin, submessage);
            final String requestData = new String(submessage.getRequestData());
            final int requestTypeInt = submessage.getRequestType();
            final int responseTypeInt = submessage.getResponseType();

            final String hardTokenSN = null;
            result = certificateRequestSession.processCertReq(admin, userdatavo, requestData, requestTypeInt,
                    hardTokenSN, responseTypeInt);
        } else {
            switch (submessage.getRequestType()) {
            case CertificateRequestRequest.REQUEST_TYPE_PKCS10:
                Certificate cert = null;
                PKCS10RequestMessage req = RequestMessageUtils
                        .genPKCS10RequestMessage(submessage.getRequestData());
                req.setUsername(submessage.getUsername());
                req.setPassword(submessage.getPassword());
                IResponseMessage resp = signSession.createCertificate(admin, req, X509ResponseMessage.class,
                        null);
                cert = CertTools.getCertfromByteArray(resp.getResponseMessage());
                if (submessage.getResponseType() == CertificateRequestRequest.RESPONSE_TYPE_CERTIFICATE) {
                    result = cert.getEncoded();
                } else {
                    result = signSession.createPKCS7(admin, cert, true);
                }
                break;
            case CertificateRequestRequest.REQUEST_TYPE_SPKAC:
                ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(submessage.getRequestData()));
                ASN1Sequence spkac = (ASN1Sequence) in.readObject();
                in.close();
                NetscapeCertRequest nscr = new NetscapeCertRequest(spkac);
                cert = signSession.createCertificate(admin, submessage.getUsername(), submessage.getPassword(),
                        nscr.getPublicKey());
                if (submessage.getResponseType() == CertificateRequestRequest.RESPONSE_TYPE_CERTIFICATE) {
                    result = cert.getEncoded();
                } else if (submessage.getResponseType() == CertificateRequestRequest.RESPONSE_TYPE_PKCS7) {
                    result = signSession.createPKCS7(admin, cert, true);
                } else if (submessage
                        .getResponseType() == CertificateRequestRequest.RESPONSE_TYPE_PKCS7WITHCHAIN) {
                    // Read certificate chain
                    ArrayList<Certificate> certList = new ArrayList<Certificate>();
                    certList.add(cert);
                    certList.addAll(
                            caSession.getCA(Admin.getInternalAdmin(), CertTools.getIssuerDN(cert).hashCode())
                                    .getCertificateChain());
                    // Create large certificate-only PKCS7
                    CertificateFactory cf = CertificateFactory.getInstance("X.509");
                    CertPath certPath = cf
                            .generateCertPath(new ByteArrayInputStream(CertTools.getPEMFromCerts(certList)));
                    result = certPath.getEncoded("PKCS7");
                } else {
                    return new CertificateRequestResponse(submessage.getRequestId(), false,
                            MSG_UNSUPPORTED_RESPONSE_TYPE, null, null);
                }
                break;
            case CertificateRequestRequest.REQUEST_TYPE_CRMF:
                // Extract request in a format that EJBCA can process
                CertReqMessages certReqMessages = CertReqMessages
                        .getInstance(new ASN1InputStream(submessage.getRequestData()).readObject());
                PKIMessage msg = new PKIMessage(new PKIHeader(new DERInteger(2),
                        new GeneralName(new X509Name("CN=unused")), new GeneralName(new X509Name("CN=unused"))),
                        new PKIBody(certReqMessages, 2)); // [2] CertReqMessages --Certification Request
                CrmfRequestMessage crmfReq = new CrmfRequestMessage(msg, null, true, null);
                crmfReq.setUsername(submessage.getUsername());
                crmfReq.setPassword(submessage.getPassword());
                // Request and extract certificate from response
                IResponseMessage response = signSession.createCertificate(admin, crmfReq,
                        org.ejbca.core.protocol.cmp.CmpResponseMessage.class, null);
                ASN1InputStream ais = new ASN1InputStream(
                        new ByteArrayInputStream(response.getResponseMessage()));
                CertRepMessage certRepMessage = PKIMessage.getInstance(ais.readObject()).getBody().getCp();
                InputStream inStream = new ByteArrayInputStream(certRepMessage.getResponse(0)
                        .getCertifiedKeyPair().getCertOrEncCert().getCertificate().getEncoded());
                cert = CertificateFactory.getInstance("X.509").generateCertificate(inStream);
                inStream.close();
                // Convert to the right response type
                if (submessage.getResponseType() == CertificateRequestRequest.RESPONSE_TYPE_CERTIFICATE) {
                    result = cert.getEncoded();
                } else if (submessage.getResponseType() == CertificateRequestRequest.RESPONSE_TYPE_PKCS7) {
                    result = signSession.createPKCS7(admin, cert, false);
                } else if (submessage
                        .getResponseType() == CertificateRequestRequest.RESPONSE_TYPE_PKCS7WITHCHAIN) {
                    // Read certificate chain
                    ArrayList<Certificate> certList = new ArrayList<Certificate>();
                    certList.add(cert);
                    certList.addAll(
                            caSession.getCA(Admin.getInternalAdmin(), CertTools.getIssuerDN(cert).hashCode())
                                    .getCertificateChain());
                    // Create large certificate-only PKCS7
                    CertificateFactory cf = CertificateFactory.getInstance("X.509");
                    CertPath certPath = cf
                            .generateCertPath(new ByteArrayInputStream(CertTools.getPEMFromCerts(certList)));
                    result = certPath.getEncoded("PKCS7");
                } else {
                    return new CertificateRequestResponse(submessage.getRequestId(), false,
                            MSG_UNSUPPORTED_RESPONSE_TYPE, null, null);
                }
                break;
            default:
                return new CertificateRequestResponse(submessage.getRequestId(), false,
                        MSG_UNSUPPORTED_REQUEST_TYPE, null, null);
            }
        }

        // Return the response when we have response data (byte[])
        return new CertificateRequestResponse(submessage.getRequestId(), true, null,
                submessage.getResponseType(), result);
    } catch (Exception e) {
        if (log.isDebugEnabled()) {
            log.debug("External RA request generated an error: " + e.getMessage());
        }
        return new CertificateRequestResponse(submessage.getRequestId(), false, "Error " + e.getMessage(), null,
                null);
    }
}

From source file:org.ejbca.ui.cli.Asn1Dump.java

License:Open Source License

public void execute(String[] args) throws ErrorAdminCommandException {
    if (args.length < 2) {
        getLogger().info(/*from ww  w  . j a v  a  2 s  .c  om*/
                "Usage: " + getCommand() + " <filename-of-pem-encoded-certs|filename-of-der-encoded-asn1>");
        return;
    }
    try {
        String filename = args[1];
        boolean iscert = true;
        Collection<Certificate> coll = null;
        CryptoProviderTools.installBCProvider();
        try {
            coll = CertTools.getCertsFromPEM(filename);
            if (coll.isEmpty()) {
                iscert = false;
            }
        } catch (Exception e) {
            iscert = false;
        }
        if (!iscert) {
            ASN1InputStream ais = new ASN1InputStream(new FileInputStream(filename));
            DERObject obj = ais.readObject();
            String dump = ASN1Dump.dumpAsString(obj);
            getLogger().info(dump);
        } else {
            Iterator<Certificate> iter = coll.iterator();
            while (iter.hasNext()) {
                Certificate cert = iter.next();
                String dump = ASN1Dump.dumpAsString(cert);
                getLogger().info(dump);
            }
        }
    } catch (Exception e) {
        throw new ErrorAdminCommandException(e);
    }

}

From source file:org.ejbca.ui.cli.Asn1DumpCommand.java

License:Open Source License

@Override
public CommandResult execute(ParameterContainer parameters) {
    String filename = parameters.get(FILENAME_KEY);
    boolean iscert = true;
    Collection<Certificate> coll = null;
    CryptoProviderTools.installBCProvider();
    try {/*from  w ww .j a v a 2 s  .  c  o  m*/
        try {
            coll = CertTools.getCertsFromPEM(filename);
            if (coll.isEmpty()) {
                iscert = false;
            }
        } catch (CertificateParsingException e) {
            iscert = false;
        }
        if (!iscert) {
            ASN1InputStream ais = new ASN1InputStream(new FileInputStream(filename));
            try {
                ASN1Primitive obj = ais.readObject();
                ais.close();
                String dump = ASN1Dump.dumpAsString(obj);
                log.info(dump);

            } catch (IOException e) {
                //None of the above.
                log.error("File " + filename
                        + " does not seem to contain either a PEM or DER encoded certificate.");
                return CommandResult.FUNCTIONAL_FAILURE;
            }
        } else {
            for (Certificate cert : coll) {
                String dump = ASN1Dump.dumpAsString(cert);
                log.info(dump);
            }
        }
    } catch (FileNotFoundException e) {
        log.error("Error: No such file " + filename);
        return CommandResult.FUNCTIONAL_FAILURE;
    }
    return CommandResult.SUCCESS;

}

From source file:org.ejbca.ui.cli.ca.CaImportCRLCommand.java

License:Open Source License

/**
 * Return a CRL reason code from a CRL entry, or RevokedCertInfo.REVOCATION_REASON_UNSPECIFIED if a reson code extension does not exist
 *//* ww  w  .j  a v a 2s  .  c o m*/
private int getCRLReasonValue(final X509CRLEntry entry) throws IOException {
    int reason = RevokedCertInfo.REVOCATION_REASON_UNSPECIFIED;
    if ((entry != null) && entry.hasExtensions()) {
        final byte[] bytes = entry.getExtensionValue(Extension.reasonCode.getId());
        if (bytes != null) {
            ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bytes));
            final ASN1OctetString octs = (ASN1OctetString) aIn.readObject();
            aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets()));
            final ASN1Primitive obj = aIn.readObject();
            if (obj != null) {
                try {
                    final ASN1Enumerated ext = (ASN1Enumerated) obj;
                    reason = ext.getValue().intValue();
                } catch (ClassCastException e) {
                    // this was not a reason code, very strange
                    log.info("Reason code extension did not contain DEREnumerated, is this CRL corrupt?. "
                            + obj.getClass().getName());
                }
            }
        }
    }
    return reason;
}

From source file:org.ejbca.ui.cli.ca.CaRenewCACommand.java

License:Open Source License

private static String computeSubjectKeyIdentifier(final X509Certificate certificate) {
    ASN1InputStream asn1InputStream = new ASN1InputStream(
            new ByteArrayInputStream(certificate.getPublicKey().getEncoded()));
    try {/*from   w ww  . j  a  va2  s  .co  m*/
        try {
            SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo((ASN1Sequence) asn1InputStream.readObject());
            X509ExtensionUtils utils = new X509ExtensionUtils(SHA1DigestCalculator.buildSha1Instance());
            SubjectKeyIdentifier ski = utils.createSubjectKeyIdentifier(spki);
            return new String(Hex.encode(ski.getKeyIdentifier()));

        } catch (IOException e) {
            return "n/a";
        } finally {
            asn1InputStream.close();
        }
    } catch (IOException e) {
        throw new IllegalStateException("Unknown IOException was caught.", e);
    }
}

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

License:Open Source License

private CMPCertificate[] getCMPCerts(Certificate cert) throws CertificateEncodingException, IOException {
    ASN1InputStream ins = new ASN1InputStream(cert.getEncoded());
    ASN1Primitive pcert = ins.readObject();
    ins.close();/*from ww  w . j  ava  2 s  .c o m*/
    org.bouncycastle.asn1.x509.Certificate c = org.bouncycastle.asn1.x509.Certificate
            .getInstance(pcert.toASN1Primitive());
    CMPCertificate[] res = { new CMPCertificate(c) };
    return res;
}

From source file:org.ejbca.ui.cmpclient.commands.ConfirmationRequestCommand.java

License:Open Source License

@Override
public CommandResult handleCMPResponse(byte[] response, ParameterContainer parameters) throws Exception {
    PKIMessage respObject = null;//  w  ww. java2  s .  c  o  m
    ASN1InputStream asn1InputStream = new ASN1InputStream(new ByteArrayInputStream(response));
    try {
        respObject = PKIMessage.getInstance(asn1InputStream.readObject());
    } finally {
        asn1InputStream.close();
    }
    if (respObject == null) {
        log.error("ERROR. Cannot construct the response object");
        return CommandResult.FUNCTIONAL_FAILURE;
    }

    PKIBody body = respObject.getBody();
    int tag = body.getType();
    if (tag == 19) {
        log.info("Recieved CmpConfirmResponse");
    } else {
        log.error("Error: CmpConfirmResponse should be recieved. Instead, received response with tag " + tag);
    }
    PKIConfirmContent n = (PKIConfirmContent) body.getContent();

    if (n.toASN1Primitive().equals(DERNull.INSTANCE)) {
        log.info("CmpConfirmResponse contains DERNull as expected.");
        return CommandResult.SUCCESS;
    } else {
        log.error("Error: CmpConfirmResponse should contain DERNull. It did not.");
    }
    return CommandResult.FUNCTIONAL_FAILURE;
}

From source file:org.ejbca.ui.cmpclient.commands.CrmfRequestCommand.java

License:Open Source License

@Override
public PKIMessage generatePKIMessage(final ParameterContainer parameters) throws Exception {

    final boolean verbose = parameters.containsKey(VERBOSE_KEY);

    final X500Name userDN = new X500Name(parameters.get(SUBJECTDN_KEY));
    final X500Name issuerDN = new X500Name(parameters.get(ISSUERDN_KEY));

    String authmodule = parameters.get(AUTHENTICATION_MODULE_KEY);
    String endentityPassword = "";
    if (authmodule != null && StringUtils.equals(authmodule, CmpConfiguration.AUTHMODULE_REG_TOKEN_PWD)) {
        endentityPassword = parameters.containsKey(AUTHENTICATION_PARAM_KEY)
                ? parameters.get(AUTHENTICATION_PARAM_KEY)
                : "foo123";
    }//from  w ww  .  j  a  v a2  s .  c o m

    String altNames = parameters.get(ALTNAME_KEY);
    String serno = parameters.get(SERNO_KEY);
    BigInteger customCertSerno = null;
    if (serno != null) {
        customCertSerno = new BigInteger(serno, 16);
    }
    boolean includePopo = parameters.containsKey(INCLUDE_POPO_KEY);

    if (verbose) {
        log.info("Creating CRMF request with: SubjectDN=" + userDN.toString());
        log.info("Creating CRMF request with: IssuerDN=" + issuerDN.toString());
        log.info("Creating CRMF request with: AuthenticationModule=" + authmodule);
        log.info("Creating CRMF request with: EndEntityPassword=" + endentityPassword);
        log.info("Creating CRMF request with: SubjectAltName=" + altNames);
        log.info("Creating CRMF request with: CustomCertSerno="
                + (customCertSerno == null ? "" : customCertSerno.toString(16)));
        log.info("Creating CRMF request with: IncludePopo=" + includePopo);
    }

    final KeyPair keys = KeyTools.genKeys("1024", AlgorithmConstants.KEYALGORITHM_RSA);
    final byte[] nonce = CmpClientMessageHelper.getInstance().createSenderNonce();
    final byte[] transid = CmpClientMessageHelper.getInstance().createSenderNonce();

    // We should be able to back date the start time when allow validity
    // override is enabled in the certificate profile
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.DAY_OF_WEEK, -1);
    cal.set(Calendar.MILLISECOND, 0); // Certificates don't use milliseconds
    // in validity
    Date notBefore = cal.getTime();
    cal.add(Calendar.DAY_OF_WEEK, 3);
    cal.set(Calendar.MILLISECOND, 0); // Certificates don't use milliseconds
    org.bouncycastle.asn1.x509.Time nb = new org.bouncycastle.asn1.x509.Time(notBefore);
    // in validity
    Date notAfter = cal.getTime();
    org.bouncycastle.asn1.x509.Time na = new org.bouncycastle.asn1.x509.Time(notAfter);

    ASN1EncodableVector optionalValidityV = new ASN1EncodableVector();
    optionalValidityV.add(new DERTaggedObject(true, 0, nb));
    optionalValidityV.add(new DERTaggedObject(true, 1, na));
    OptionalValidity myOptionalValidity = OptionalValidity.getInstance(new DERSequence(optionalValidityV));

    CertTemplateBuilder myCertTemplate = new CertTemplateBuilder();
    myCertTemplate.setValidity(myOptionalValidity);
    if (issuerDN != null) {
        myCertTemplate.setIssuer(issuerDN);
    }
    myCertTemplate.setSubject(userDN);
    byte[] bytes = keys.getPublic().getEncoded();
    ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);
    ASN1InputStream dIn = new ASN1InputStream(bIn);
    SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo((ASN1Sequence) dIn.readObject());
    dIn.close();
    myCertTemplate.setPublicKey(keyInfo);

    // Create standard extensions
    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    ASN1OutputStream dOut = new ASN1OutputStream(bOut);
    ExtensionsGenerator extgen = new ExtensionsGenerator();
    if (altNames != null) {
        GeneralNames san = CertTools.getGeneralNamesFromAltName(altNames);
        dOut.writeObject(san);
        byte[] value = bOut.toByteArray();
        extgen.addExtension(Extension.subjectAlternativeName, false, value);
    }

    // KeyUsage
    int bcku = 0;
    bcku = KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.nonRepudiation;
    KeyUsage ku = new KeyUsage(bcku);
    extgen.addExtension(Extension.keyUsage, false, new DERBitString(ku));

    // Make the complete extension package
    Extensions exts = extgen.generate();

    myCertTemplate.setExtensions(exts);
    if (customCertSerno != null) {
        // Add serialNumber to the certTemplate, it is defined as a MUST NOT be used in RFC4211, but we will use it anyway in order
        // to request a custom certificate serial number (something not standard anyway)
        myCertTemplate.setSerialNumber(new ASN1Integer(customCertSerno));
    }

    CertRequest myCertRequest = new CertRequest(4, myCertTemplate.build(), null);

    // POPO
    /*
     * PKMACValue myPKMACValue = new PKMACValue( new AlgorithmIdentifier(new
     * ASN1ObjectIdentifier("8.2.1.2.3.4"), new DERBitString(new byte[] { 8,
     * 1, 1, 2 })), new DERBitString(new byte[] { 12, 29, 37, 43 }));
     * 
     * POPOPrivKey myPOPOPrivKey = new POPOPrivKey(new DERBitString(new
     * byte[] { 44 }), 2); //take choice pos tag 2
     * 
     * POPOSigningKeyInput myPOPOSigningKeyInput = new POPOSigningKeyInput(
     * myPKMACValue, new SubjectPublicKeyInfo( new AlgorithmIdentifier(new
     * ASN1ObjectIdentifier("9.3.3.9.2.2"), new DERBitString(new byte[] { 2,
     * 9, 7, 3 })), new byte[] { 7, 7, 7, 4, 5, 6, 7, 7, 7 }));
     */
    ProofOfPossession myProofOfPossession = null;
    if (includePopo) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DEROutputStream mout = new DEROutputStream(baos);
        mout.writeObject(myCertRequest);
        mout.close();
        byte[] popoProtectionBytes = baos.toByteArray();
        String sigalg = AlgorithmTools.getSignAlgOidFromDigestAndKey(null, keys.getPrivate().getAlgorithm())
                .getId();
        Signature sig = Signature.getInstance(sigalg, "BC");
        sig.initSign(keys.getPrivate());
        sig.update(popoProtectionBytes);
        DERBitString bs = new DERBitString(sig.sign());
        POPOSigningKey myPOPOSigningKey = new POPOSigningKey(null,
                new AlgorithmIdentifier(new ASN1ObjectIdentifier(sigalg)), bs);
        myProofOfPossession = new ProofOfPossession(myPOPOSigningKey);
    } else {
        // raVerified POPO (meaning there is no POPO)
        myProofOfPossession = new ProofOfPossession();
    }

    AttributeTypeAndValue av = new AttributeTypeAndValue(CRMFObjectIdentifiers.id_regCtrl_regToken,
            new DERUTF8String(endentityPassword));
    AttributeTypeAndValue[] avs = { av };

    CertReqMsg myCertReqMsg = new CertReqMsg(myCertRequest, myProofOfPossession, avs);

    CertReqMessages myCertReqMessages = new CertReqMessages(myCertReqMsg);

    PKIHeaderBuilder myPKIHeader = new PKIHeaderBuilder(2, new GeneralName(userDN), new GeneralName(issuerDN));

    myPKIHeader.setMessageTime(new ASN1GeneralizedTime(new Date()));
    // senderNonce
    myPKIHeader.setSenderNonce(new DEROctetString(nonce));
    // TransactionId
    myPKIHeader.setTransactionID(new DEROctetString(transid));
    myPKIHeader.setProtectionAlg(null);
    myPKIHeader.setSenderKID(new byte[0]);

    PKIBody myPKIBody = new PKIBody(0, myCertReqMessages); // initialization
    // request
    PKIMessage myPKIMessage = new PKIMessage(myPKIHeader.build(), myPKIBody);

    return myPKIMessage;
}