Example usage for org.bouncycastle.asn1.x509 X509Extensions getExtension

List of usage examples for org.bouncycastle.asn1.x509 X509Extensions getExtension

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.x509 X509Extensions getExtension.

Prototype

public X509Extension getExtension(ASN1ObjectIdentifier oid) 

Source Link

Document

return the extension represented by the object identifier passed in.

Usage

From source file:org.candlepin.util.X509CRLStreamWriter.java

License:Open Source License

protected void writeToEmptyCrl(OutputStream out) throws IOException {
    ASN1InputStream asn1in = null;
    try {//from   w ww .j a  v  a2  s .  c  o m
        asn1in = new ASN1InputStream(crlIn);
        DERSequence certListSeq = (DERSequence) asn1in.readObject();
        CertificateList certList = new CertificateList(certListSeq);
        X509CRLHolder oldCrl = new X509CRLHolder(certList);

        X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(oldCrl.getIssuer(), new Date());
        crlBuilder.addCRL(oldCrl);

        Date now = new Date();
        Date oldNextUpdate = certList.getNextUpdate().getDate();
        Date oldThisUpdate = certList.getThisUpdate().getDate();

        Date nextUpdate = new Date(now.getTime() + (oldNextUpdate.getTime() - oldThisUpdate.getTime()));
        crlBuilder.setNextUpdate(nextUpdate);

        for (Object o : oldCrl.getExtensionOIDs()) {
            ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) o;
            X509Extension ext = oldCrl.getExtension(oid);

            if (oid.equals(X509Extension.cRLNumber)) {
                DEROctetString octet = (DEROctetString) ext.getValue().getDERObject();
                DERInteger currentNumber = (DERInteger) DERTaggedObject.fromByteArray(octet.getOctets());
                DERInteger nextNumber = new DERInteger(currentNumber.getValue().add(BigInteger.ONE));

                crlBuilder.addExtension(oid, ext.isCritical(), nextNumber);
            } else if (oid.equals(X509Extension.authorityKeyIdentifier)) {
                crlBuilder.addExtension(oid, ext.isCritical(),
                        new AuthorityKeyIdentifierStructure(ext.getValue().getDEREncoded()));
            }
        }

        for (DERSequence entry : newEntries) {
            // XXX: This is all a bit messy considering the user already passed in the serial, date
            // and reason.
            BigInteger serial = ((DERInteger) entry.getObjectAt(0)).getValue();
            Date revokeDate = ((Time) entry.getObjectAt(1)).getDate();
            int reason = CRLReason.unspecified;
            if (entry.size() == 3) {
                X509Extensions extensions = (X509Extensions) entry.getObjectAt(2);
                X509Extension reasonExt = extensions.getExtension(X509Extension.reasonCode);

                if (reasonExt != null) {
                    reason = ((DEREnumerated) reasonExt.getParsedValue()).getValue().intValue();
                }
            }
            crlBuilder.addCRLEntry(serial, revokeDate, reason);
        }

        RSAKeyParameters keyParams = new RSAKeyParameters(true, key.getModulus(), key.getPrivateExponent());

        signingAlg = oldCrl.toASN1Structure().getSignatureAlgorithm();
        digestAlg = new DefaultDigestAlgorithmIdentifierFinder().find(signingAlg);

        ContentSigner s;
        try {
            s = new BcRSAContentSignerBuilder(signingAlg, digestAlg).build(keyParams);
            X509CRLHolder newCrl = crlBuilder.build(s);
            out.write(newCrl.getEncoded());
        } catch (OperatorCreationException e) {
            throw new IOException("Could not sign CRL", e);
        }
    } finally {
        IOUtils.closeQuietly(asn1in);
    }
}

From source file:org.cesecore.certificates.ocsp.CanLogCache.java

License:Open Source License

public byte[] getOcspResponse(AuthenticationToken authenticationToken, byte[] request,
        X509Certificate[] requestCertificates, String remoteAddress, String remoteHost)
        throws AuthorizationDeniedException, MalformedRequestException {
    initiateIfNecessary();//from  ww w.  j a  v a2s .c o m

    // Validate byte array.
    if (request.length > MAX_REQUEST_SIZE) {
        final String msg = intres.getLocalizedMessage("request.toolarge", MAX_REQUEST_SIZE, request.length);
        throw new MalformedRequestException(msg);
    }

    byte[] respBytes = null;

    final Date startTime = new Date();

    OCSPResp ocspResponse = null;

    int localTransactionId = TransactionCounter.INSTANCE.getTransactionNumber();
    // Create the transaction logger for this transaction.
    TransactionLogger transactionLogger = new TransactionLogger(localTransactionId,
            GuidHolder.INSTANCE.getGlobalUid(), remoteAddress);
    // Create the audit logger for this transaction.
    AuditLogger auditLogger = new AuditLogger("", localTransactionId, GuidHolder.INSTANCE.getGlobalUid(),
            remoteAddress);

    // Start logging process time after we have received the request
    transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
    auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
    auditLogger.paramPut(AuditLogger.OCSPREQUEST, new String(Hex.encode(request)));

    OCSPReq req;

    OCSPRespGenerator responseGenerator = new OCSPRespGenerator();

    try {
        try {
            req = translateRequestFromByteArray(request, remoteAddress, transactionLogger);

            // Get the certificate status requests that are inside this OCSP req
            Req[] ocspRequests = req.getRequestList();

            if (ocspRequests.length <= 0) {
                String infoMsg = intres.getLocalizedMessage("ocsp.errornoreqentities");
                log.info(infoMsg);
                throw new MalformedRequestException(infoMsg);
            }
            int maxRequests = 100;
            if (ocspRequests.length > maxRequests) {
                String infoMsg = intres.getLocalizedMessage("ocsp.errortoomanyreqentities", maxRequests);
                log.info(infoMsg);
                throw new MalformedRequestException(infoMsg);
            }

            if (log.isDebugEnabled()) {
                log.debug("The OCSP request contains " + ocspRequests.length + " simpleRequests.");
            }

            transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
            auditLogger.paramPut(AuditLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);

            CryptoTokenAndChain signerTokenAndChain = null;

            long maxAge = OcspConfiguration.getMaxAge(CertificateProfileConstants.CERTPROFILE_NO_PROFILE);
            long nextUpdate = OcspConfiguration
                    .getUntilNextUpdate(CertificateProfileConstants.CERTPROFILE_NO_PROFILE);

            // Add standard response extensions
            Hashtable<DERObjectIdentifier, X509Extension> responseExtensions = getStandardResponseExtensions(
                    req);

            // Look for extension OIDs
            final Collection<String> extensionOids = OcspConfiguration.getExtensionOids();

            // Look over the status requests
            List<OCSPResponseItem> responseList = new ArrayList<OCSPResponseItem>();
            for (Req ocspRequest : ocspRequests) {
                CertificateID certId = ocspRequest.getCertID();

                transactionLogger.paramPut(TransactionLogger.SERIAL_NOHEX,
                        certId.getSerialNumber().toByteArray());
                // TODO:find text version of this or find out if it should be something else
                transactionLogger.paramPut(TransactionLogger.DIGEST_ALGOR, certId.getHashAlgOID());
                transactionLogger.paramPut(TransactionLogger.ISSUER_NAME_HASH, certId.getIssuerNameHash());
                transactionLogger.paramPut(TransactionLogger.ISSUER_KEY, certId.getIssuerKeyHash());
                auditLogger.paramPut(AuditLogger.ISSUER_KEY, certId.getIssuerKeyHash());
                auditLogger.paramPut(AuditLogger.SERIAL_NOHEX, certId.getSerialNumber().toByteArray());
                auditLogger.paramPut(AuditLogger.ISSUER_NAME_HASH, certId.getIssuerNameHash());

                byte[] hashbytes = certId.getIssuerNameHash();
                String hash = null;
                if (hashbytes != null) {
                    hash = new String(Hex.encode(hashbytes));
                }
                String infoMsg = intres.getLocalizedMessage("ocsp.inforeceivedrequest",
                        certId.getSerialNumber().toString(16), hash, remoteAddress);
                log.info(infoMsg);

                // Locate the CA which gave out the certificate
                signerTokenAndChain = getTokenAndChainCache().get(certId);
                /*
                 * if the certId was issued by an unknown CA 
                 * 
                 * The algorithm here: 
                 * We will sign the response with the CA that issued the last certificate(certId) in the request. If the issuing CA is not available on 
                 * this server, we sign the response with the default responderId (from params in web.xml). We have to look up the ca-certificate for 
                 * each certId in the request though, as we will check for revocation on the ca-cert as well when checking for revocation on the certId.
                 */

                if (signerTokenAndChain != null) {
                    transactionLogger.paramPut(TransactionLogger.ISSUER_NAME_DN,
                            signerTokenAndChain.getCaCertificate().getSubjectDN().getName());
                } else {
                    // We could not find certificate for this request so get certificate for default responder
                    signerTokenAndChain = getTokenAndChainCache().getForDefaultResponder();
                    if (signerTokenAndChain != null) {
                        String errMsg = intres.getLocalizedMessage("ocsp.errorfindcacertusedefault",
                                new String(Hex.encode(certId.getIssuerNameHash())));
                        log.info(errMsg);
                        // If we can not find the CA, answer UnknowStatus
                        responseList.add(new OCSPResponseItem(certId, new UnknownStatus(), nextUpdate));
                        transactionLogger.paramPut(TransactionLogger.CERT_STATUS,
                                OCSPResponseItem.OCSP_UNKNOWN);
                        transactionLogger.writeln();
                        continue;
                    } else {
                        String errMsg = intres.getLocalizedMessage("ocsp.errorfindcacert",
                                new String(Hex.encode(certId.getIssuerNameHash())),
                                OcspConfiguration.getDefaultResponderId());
                        log.error(errMsg);
                        continue;
                    }
                }

                /*
                 * Implement logic according to chapter 2.7 in RFC2560
                 * 
                 * 2.7 CA Key Compromise If an OCSP responder knows that a particular CA's private key has been compromised, it MAY return the revoked
                 * state for all certificates issued by that CA.
                 */
                final org.bouncycastle.ocsp.CertificateStatus certStatus;
                transactionLogger.paramPut(TransactionLogger.CERT_STATUS, OCSPResponseItem.OCSP_GOOD); // it seems to be correct

                // Check if the cacert (or the default responderid) is revoked
                final CertificateStatus signerIssuerCertStatus = certificateStoreSession.getStatus(
                        CertTools.getSubjectDN(signerTokenAndChain.getCaCertificate()),
                        CertTools.getSerialNumber(signerTokenAndChain.getCaCertificate()));

                String subjectDn = signerTokenAndChain.getCaCertificate().getSubjectDN().getName();
                if (!signerIssuerCertStatus.equals(CertificateStatus.REVOKED)) {

                    // Check if cert is revoked
                    final CertificateStatus status = certificateStoreSession.getStatus(subjectDn,
                            certId.getSerialNumber());

                    /* If we have different maxAge and untilNextUpdate for different certificate profiles, we have to fetch these
                     values now that we have fetched the certificate status, that includes certificate profile.*/
                    nextUpdate = OcspConfiguration.getUntilNextUpdate(status.certificateProfileId);
                    maxAge = OcspConfiguration.getMaxAge(status.certificateProfileId);
                    if (log.isDebugEnabled()) {
                        log.debug("Set nextUpdate=" + nextUpdate + ", and maxAge=" + maxAge
                                + " for certificateProfileId=" + status.certificateProfileId);
                    }

                    final String sStatus;
                    if (status.equals(CertificateStatus.NOT_AVAILABLE)) {
                        // No revocation info available for this cert, handle it
                        if (log.isDebugEnabled()) {
                            log.debug("Unable to find revocation information for certificate with serial '"
                                    + certId.getSerialNumber().toString(16) + "'" + " from issuer '" + subjectDn
                                    + "'");
                        }
                        /* 
                         * If we do not treat non existing certificates as good
                         * OR
                         * we don't actually handle requests for the CA issuing the certificate asked about
                         * then we return unknown 
                         * */
                        if ((!OcspConfiguration.getNonExistingIsGood())
                                || (getTokenAndChainCache().get(certId) == null)) {
                            sStatus = "unknown";
                            certStatus = new UnknownStatus();

                        } else {
                            sStatus = "good";
                            certStatus = null; // null means "good" in OCSP

                        }
                    } else if (status.equals(CertificateStatus.REVOKED)) {
                        // Revocation info available for this cert, handle it
                        sStatus = "revoked";
                        certStatus = new RevokedStatus(
                                new RevokedInfo(new DERGeneralizedTime(status.revocationDate),
                                        new CRLReason(status.revocationReason)));
                    } else {
                        sStatus = "good";
                        certStatus = null;

                    }
                    infoMsg = intres.getLocalizedMessage("ocsp.infoaddedstatusinfo", sStatus,
                            certId.getSerialNumber().toString(16), subjectDn);
                    log.info(infoMsg);
                    responseList.add(new OCSPResponseItem(certId, certStatus, nextUpdate));

                } else {
                    certStatus = new RevokedStatus(
                            new RevokedInfo(new DERGeneralizedTime(signerIssuerCertStatus.revocationDate),
                                    new CRLReason(signerIssuerCertStatus.revocationReason)));
                    infoMsg = intres.getLocalizedMessage("ocsp.infoaddedstatusinfo", "revoked",
                            certId.getSerialNumber().toString(16), subjectDn);
                    log.info(infoMsg);
                    responseList.add(new OCSPResponseItem(certId, certStatus, nextUpdate));

                }
                for (String oidstr : extensionOids) {
                    DERObjectIdentifier oid = new DERObjectIdentifier(oidstr);
                    X509Extensions reqexts = req.getRequestExtensions();
                    if (reqexts != null) {
                        X509Extension ext = reqexts.getExtension(oid);
                        if (null != ext) {
                            // We found an extension, call the extension class
                            if (log.isDebugEnabled()) {
                                log.debug("Found OCSP extension oid: " + oidstr);
                            }
                            OCSPExtension extObj = OcspExtensionsCache.INSTANCE.getExtensions().get(oidstr);
                            if (extObj != null) {
                                // Find the certificate from the certId
                                X509Certificate cert = null;
                                cert = (X509Certificate) certificateStoreSession
                                        .findCertificateByIssuerAndSerno(subjectDn, certId.getSerialNumber());
                                if (cert != null) {
                                    // Call the OCSP extension
                                    Map<DERObjectIdentifier, X509Extension> retext = extObj.process(
                                            requestCertificates, remoteAddress, remoteHost, cert, certStatus);
                                    if (retext != null) {
                                        // Add the returned X509Extensions to the responseExtension we will add to the basic OCSP response
                                        responseExtensions.putAll(retext);
                                    } else {
                                        String errMsg = intres.getLocalizedMessage("ocsp.errorprocessextension",
                                                extObj.getClass().getName(),
                                                Integer.valueOf(extObj.getLastErrorCode()));
                                        log.error(errMsg);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (signerTokenAndChain != null) {
                // Add responseExtensions
                X509Extensions exts = new X509Extensions(responseExtensions);
                // generate the signed response object

                final X509Certificate[] signerChain = signerTokenAndChain.getChain();
                final PrivateKey privateKey = signerTokenAndChain.getPrivateKey();
                final String privateKeyProvider = signerTokenAndChain.getSignProviderName();
                BasicOCSPResp basicresp = signOcspResponse(req, responseList, exts, signerChain, privateKey,
                        privateKeyProvider);
                ocspResponse = responseGenerator.generate(OCSPRespGenerator.SUCCESSFUL, basicresp);
                auditLogger.paramPut(AuditLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
                transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
            } else {
                // Only unknown CAs in requests and no default responder's cert
                String errMsg = intres.getLocalizedMessage("ocsp.errornocacreateresp");
                log.error(errMsg);
                throw new OcspFailureException(errMsg);
            }
        } catch (MalformedRequestException e) {
            transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            log.info(errMsg);
            if (log.isDebugEnabled()) {
                log.debug(errMsg, e);
            }
            ocspResponse = responseGenerator.generate(OCSPRespGenerator.MALFORMED_REQUEST, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespGenerator.MALFORMED_REQUEST);
            transactionLogger.writeln();
            auditLogger.paramPut(AuditLogger.STATUS, OCSPRespGenerator.MALFORMED_REQUEST);
        } catch (SignRequestException e) {
            transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            log.info(errMsg); // No need to log the full exception here
            ocspResponse = responseGenerator.generate(OCSPRespGenerator.SIG_REQUIRED, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespGenerator.SIG_REQUIRED);
            transactionLogger.writeln();
            auditLogger.paramPut(AuditLogger.STATUS, OCSPRespGenerator.SIG_REQUIRED);
        } catch (SignRequestSignatureException e) {
            transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            log.info(errMsg); // No need to log the full exception here
            ocspResponse = responseGenerator.generate(OCSPRespGenerator.UNAUTHORIZED, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
            transactionLogger.writeln();
            auditLogger.paramPut(AuditLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
        } catch (NoSuchAlgorithmException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (CertificateException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (ExtendedCAServiceNotActiveException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (IllegalExtendedCAServiceRequestException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (ExtendedCAServiceRequestException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (CADoesntExistsException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (IllegalCryptoTokenException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (CryptoTokenOfflineException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        }

        try {
            respBytes = ocspResponse.getEncoded();
            auditLogger.paramPut(AuditLogger.OCSPRESPONSE, new String(Hex.encode(respBytes)));
            auditLogger.writeln();
            auditLogger.flush();
            transactionLogger.flush();
            if (OcspConfiguration.getLogSafer()) {
                // See if the Errorhandler has found any problems
                if (hasErrorHandlerFailedSince(startTime)) {
                    log.info("ProbableErrorhandler reported error, cannot answer request");
                    ocspResponse = responseGenerator.generate(OCSPRespGenerator.INTERNAL_ERROR, null); // RFC 2560: responseBytes are not set on
                                                                                                       // error.
                    respBytes = ocspResponse.getEncoded();
                }
                // See if the Appender has reported any problems
                if (!CanLogCache.INSTANCE.canLog()) {
                    log.info("SaferDailyRollingFileAppender reported error, cannot answer request");
                    ocspResponse = responseGenerator.generate(OCSPRespGenerator.INTERNAL_ERROR, null); // RFC 2560: responseBytes are not set on
                                                                                                       // error.
                    respBytes = ocspResponse.getEncoded();
                }
            }
        } catch (IOException e) {
            log.error("", e);
            transactionLogger.flush();
            auditLogger.flush();
        }
    } catch (OCSPException e) {
        throw new OcspFailureException("OCSP response generation failed", e);
    }

    return respBytes;

}

From source file:org.cesecore.certificates.ocsp.CanLogCache.java

License:Open Source License

private BasicOCSPRespGenerator createOcspResponseGenerator(OCSPReq req, X509Certificate respondercert,
        int respIdType) throws OCSPException, NotSupportedException {
    if (null == req) {
        throw new IllegalArgumentException();
    }/*from  w  w  w.j  av  a2  s.  co  m*/
    BasicOCSPRespGenerator res = null;
    if (respIdType == OcspConfiguration.RESPONDERIDTYPE_NAME) {
        res = new BasicOCSPRespGenerator(new RespID(respondercert.getSubjectX500Principal()));
    } else {
        res = new BasicOCSPRespGenerator(respondercert.getPublicKey());
    }
    X509Extensions reqexts = req.getRequestExtensions();
    if (reqexts != null) {
        X509Extension ext = reqexts.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_response);
        if (null != ext) {
            // log.debug("Found extension AcceptableResponses");
            ASN1OctetString oct = ext.getValue();
            try {
                ASN1Sequence seq = ASN1Sequence.getInstance(
                        new ASN1InputStream(new ByteArrayInputStream(oct.getOctets())).readObject());
                @SuppressWarnings("unchecked")
                Enumeration<DERObjectIdentifier> en = seq.getObjects();
                boolean supportsResponseType = false;
                while (en.hasMoreElements()) {
                    DERObjectIdentifier oid = en.nextElement();
                    // log.debug("Found oid: "+oid.getId());
                    if (oid.equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic)) {
                        // This is the response type we support, so we are happy! Break the loop.
                        supportsResponseType = true;
                        log.debug("Response type supported: " + oid.getId());
                        continue;
                    }
                }
                if (!supportsResponseType) {
                    throw new NotSupportedException(
                            "Required response type not supported, this responder only supports id-pkix-ocsp-basic.");
                }
            } catch (IOException e) {
            }
        }
    }
    return res;
}

From source file:org.cesecore.certificates.ocsp.CanLogCache.java

License:Open Source License

/**
 * returns a Map of responseExtensions to be added to the BacisOCSPResponseGenerator with <code>
 * X509Extensions exts = new X509Extensions(table);
 * basicRes.setResponseExtensions(responseExtensions);
 * </code>//from w w w .  ja  v a 2  s.  c o  m
 * 
 * @param req OCSPReq
 * @return a HashMap, can be empty but not null
 */
private Hashtable<DERObjectIdentifier, X509Extension> getStandardResponseExtensions(OCSPReq req) {
    X509Extensions reqexts = req.getRequestExtensions();
    Hashtable<DERObjectIdentifier, X509Extension> result = new Hashtable<DERObjectIdentifier, X509Extension>();
    if (reqexts != null) {
        // Table of extensions to include in the response
        X509Extension ext = reqexts.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
        if (null != ext) {
            result.put(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, ext);
        }
    }
    return result;
}

From source file:org.ejbca.core.ejb.ca.sign.RSASignSessionBean.java

License:Open Source License

@Override
public IResponseMessage createCertificate(Admin admin, IRequestMessage req, Class responseClass,
        UserDataVO suppliedUserData) throws EjbcaException {
    if (log.isTraceEnabled()) {
        log.trace(">createCertificate(IRequestMessage)");
    }//from  ww  w  .  j av  a  2  s  .  c  o  m
    // Get CA that will receive request
    UserDataVO data = null;
    IResponseMessage ret = null;
    CA ca;
    if (suppliedUserData == null) {
        ca = getCAFromRequest(admin, req);
    } else {
        ca = caSession.getCA(admin, suppliedUserData.getCAId()); // Take the CAId from the supplied userdata, if any
    }
    try {
        CATokenContainer catoken = ca.getCAToken();

        // See if we need some key material to decrypt request
        if (req.requireKeyInfo()) {
            // You go figure...scep encrypts message with the public CA-cert
            req.setKeyInfo(ca.getCACertificate(), catoken.getPrivateKey(SecConst.CAKEYPURPOSE_CERTSIGN),
                    catoken.getJCEProvider());
        }
        // Verify the request
        if (req.verify() == false) {
            String msg = intres.getLocalizedMessage("signsession.popverificationfailed");
            logSession.log(admin, ca.getCAId(), LogConstants.MODULE_CA, new java.util.Date(), req.getUsername(),
                    null, LogConstants.EVENT_ERROR_CREATECERTIFICATE, msg);
            throw new SignRequestSignatureException(msg);
        }

        if (ca.isUseUserStorage() && req.getUsername() == null) {
            String msg = intres.getLocalizedMessage("signsession.nouserinrequest", req.getRequestDN());
            logSession.log(admin, ca.getCAId(), LogConstants.MODULE_CA, new java.util.Date(), req.getUsername(),
                    null, LogConstants.EVENT_ERROR_CREATECERTIFICATE, msg);
            throw new SignRequestException(msg);
            //ret.setFailInfo(FailInfo.BAD_REQUEST);
            //ret.setStatus(ResponseStatus.FAILURE);
        } else if (ca.isUseUserStorage() && req.getPassword() == null) {
            String msg = intres.getLocalizedMessage("signsession.nopasswordinrequest");
            logSession.log(admin, ca.getCAId(), LogConstants.MODULE_CA, new java.util.Date(), req.getUsername(),
                    null, LogConstants.EVENT_ERROR_CREATECERTIFICATE, msg);
            throw new SignRequestException(msg);
        } else {
            ResponseStatus status = ResponseStatus.SUCCESS;
            FailInfo failInfo = null;
            String failText = null;
            Certificate cert = null;
            try {
                // If we haven't done so yet, authenticate user. (Only if we store UserData for this CA.)
                if (ca.isUseUserStorage()) {
                    data = authUser(admin, req.getUsername(), req.getPassword());
                } else {
                    data = suppliedUserData;
                }
                PublicKey reqpk = req.getRequestPublicKey();
                if (reqpk == null) {
                    logSession.log(admin, ca.getCAId(), LogConstants.MODULE_CA, new java.util.Date(),
                            req.getUsername(), null, LogConstants.EVENT_ERROR_CREATECERTIFICATE,
                            intres.getLocalizedMessage("signsession.nokeyinrequest"));
                    throw new InvalidKeyException("Key is null!");
                }
                // We need to make sure we use the users registered CA here
                if (data.getCAId() != ca.getCAId()) {
                    failText = intres.getLocalizedMessage("signsession.wrongauthority",
                            Integer.valueOf(ca.getCAId()), Integer.valueOf(data.getCAId()));
                    status = ResponseStatus.FAILURE;
                    failInfo = FailInfo.WRONG_AUTHORITY;
                    logSession.log(admin, ca.getCAId(), LogConstants.MODULE_CA, new java.util.Date(),
                            req.getUsername(), null, LogConstants.EVENT_ERROR_CREATECERTIFICATE, failText);
                }

                if (status.equals(ResponseStatus.SUCCESS)) {
                    Date notBefore = req.getRequestValidityNotBefore(); // Optionally requested validity
                    Date notAfter = req.getRequestValidityNotAfter(); // Optionally requested validity
                    X509Extensions exts = req.getRequestExtensions(); // Optionally requested extensions
                    int keyusage = -1;
                    if (exts != null) {
                        if (log.isDebugEnabled()) {
                            log.debug(
                                    "we have extensions, see if we can override KeyUsage by looking for a KeyUsage extension in request");
                        }
                        X509Extension ext = exts.getExtension(X509Extensions.KeyUsage);
                        if (ext != null) {
                            ASN1OctetString os = ext.getValue();
                            ByteArrayInputStream bIs = new ByteArrayInputStream(os.getOctets());
                            ASN1InputStream dIs = new ASN1InputStream(bIs);
                            DERObject dob = dIs.readObject();
                            DERBitString bs = DERBitString.getInstance(dob);
                            keyusage = bs.intValue();
                            if (log.isDebugEnabled()) {
                                log.debug("We have a key usage request extension: " + keyusage);
                            }
                        }
                    }
                    String sequence = null;
                    byte[] ki = req.getRequestKeyInfo();
                    if ((ki != null) && (ki.length > 0)) {
                        sequence = new String(ki);
                    }
                    cert = createCertificate(admin, data, req.getRequestX509Name(), ca, reqpk, keyusage,
                            notBefore, notAfter, exts, sequence);
                }
            } catch (ObjectNotFoundException oe) {
                // If we didn't find the entity return error message
                log.error("User not found: ", oe);
                failText = intres.getLocalizedMessage("signsession.nosuchuser", req.getUsername());
                status = ResponseStatus.FAILURE;
                failInfo = FailInfo.INCORRECT_DATA;
                logSession.log(admin, ca.getCAId(), LogConstants.MODULE_CA, new java.util.Date(),
                        req.getUsername(), null, LogConstants.EVENT_ERROR_CREATECERTIFICATE, failText);
            }

            //Create the response message with all nonces and checks etc
            ret = req.createResponseMessage(responseClass, req, ca.getCACertificate(),
                    catoken.getPrivateKey(SecConst.CAKEYPURPOSE_CERTSIGN), catoken.getProvider());

            if ((cert == null) && (status == ResponseStatus.SUCCESS)) {
                status = ResponseStatus.FAILURE;
                failInfo = FailInfo.BAD_REQUEST;
            } else {
                ret.setCertificate(cert);
            }
            ret.setStatus(status);
            if (failInfo != null) {
                ret.setFailInfo(failInfo);
                ret.setFailText(failText);
            }
        }
        ret.create();
        // Call authentication session and tell that we are finished with this user. (Only if we store UserData for this CA.)
        if (ca.isUseUserStorage() && data != null) {
            finishUser(ca, data);
        }
    } catch (NoUniqueCertSerialNumberIndexException e) {
        cleanUserCertDataSN(data);
        throw e.ejbcaException;
    } catch (IllegalKeyException ke) {
        log.error("Key is of unknown type: ", ke);
        throw ke;
    } catch (CATokenOfflineException ctoe) {
        String msg = intres.getLocalizedMessage("error.catokenoffline", ca.getSubjectDN());
        CATokenOfflineException ex = new CATokenOfflineException(msg);
        ex.initCause(ctoe);
        throw ex;
        //} catch (EjbcaException e) {
        //    throw e;
    } catch (NoSuchProviderException e) {
        log.error("NoSuchProvider provider: ", e);
    } catch (InvalidKeyException e) {
        log.error("Invalid key in request: ", e);
    } catch (NoSuchAlgorithmException e) {
        log.error("No such algorithm: ", e);
    } catch (IOException e) {
        log.error("Cannot create response message: ", e);
    }
    if (log.isTraceEnabled()) {
        log.trace("<createCertificate(IRequestMessage)");
    }
    return ret;
}

From source file:org.ejbca.core.model.ca.caadmin.X509CA.java

License:Open Source License

/**
 * sequence is ignored by X509CA/* w  w w. j av  a 2 s  .  c om*/
 */
public Certificate generateCertificate(UserDataVO subject, X509Name requestX509Name, PublicKey publicKey,
        int keyusage, Date notBefore, Date notAfter, CertificateProfile certProfile, X509Extensions extensions,
        String sequence, PublicKey caPublicKey, PrivateKey caPrivateKey, String provider) throws Exception {

    // We must only allow signing to take place if the CA itself if on line, even if the token is on-line.
    // We have to allow expired as well though, so we can renew expired CAs
    if ((getStatus() != SecConst.CA_ACTIVE) && ((getStatus() != SecConst.CA_EXPIRED))) {
        String msg = intres.getLocalizedMessage("error.caoffline", getName(), getStatus());
        if (log.isDebugEnabled()) {
            log.debug(msg); // This is something we handle so no need to log with higher priority
        }
        throw new CAOfflineException(msg);
    }

    final String sigAlg;
    if (certProfile.getSignatureAlgorithm() == null) {
        sigAlg = getCAInfo().getCATokenInfo().getSignatureAlgorithm();
    } else {
        sigAlg = certProfile.getSignatureAlgorithm();
    }
    final X509Certificate cacert = (X509Certificate) getCACertificate();
    String dn = subject.getCertificateDN();
    // Check if this is a root CA we are creating
    final boolean isRootCA = certProfile.getType() == CertificateProfile.TYPE_ROOTCA;

    // Get certificate validity time notBefore and notAfter
    final CertificateValidity val = new CertificateValidity(subject, certProfile, notBefore, notAfter, cacert,
            isRootCA);

    final X509V3CertificateGenerator certgen = new X509V3CertificateGenerator();
    {
        // Serialnumber is either random bits, where random generator is initialized by the serno generator.
        // Or a custom serial number defined in the end entity object
        final ExtendedInformation ei = subject.getExtendedinformation();
        BigInteger customSN = ei != null ? ei.certificateSerialNumber() : null;
        if (customSN != null) {
            if (!certProfile.getAllowCertSerialNumberOverride()) {
                final String msg = intres.getLocalizedMessage(
                        "signsession.certprof_not_allowing_cert_sn_override_using_normal",
                        customSN.toString(16));
                log.info(msg);
                customSN = null;
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("Using custom serial number: " + customSN.toString(16));
                }
            }
        }
        final BigInteger serno = customSN != null ? customSN : SernoGenerator.instance().getSerno();
        certgen.setSerialNumber(serno);
    }
    certgen.setNotBefore(val.getNotBefore());
    certgen.setNotAfter(val.getNotAfter());
    certgen.setSignatureAlgorithm(sigAlg);

    // Make DNs
    if (certProfile.getUseSubjectDNSubSet()) {
        dn = certProfile.createSubjectDNSubSet(dn);
    }

    if (certProfile.getUseCNPostfix()) {
        dn = CertTools.insertCNPostfix(dn, certProfile.getCNPostfix());
    }

    X509NameEntryConverter converter = null;
    if (getUsePrintableStringSubjectDN()) {
        converter = new PrintableStringEntryConverter();
    } else {
        converter = new X509DefaultEntryConverter();
    }
    // Will we use LDAP DN order (CN first) or X500 DN order (CN last) for the subject DN
    boolean ldapdnorder = true;
    if ((getUseLdapDNOrder() == false) || (certProfile.getUseLdapDnOrder() == false)) {
        ldapdnorder = false;
    }
    X509Name subjectDNName = CertTools.stringToBcX509Name(dn, converter, ldapdnorder);
    if (certProfile.getAllowDNOverride() && (requestX509Name != null)) {
        subjectDNName = requestX509Name;
        if (log.isDebugEnabled()) {
            log.debug("Using X509Name from request instead of user's registered.");
        }
    }
    if (log.isDebugEnabled()) {
        log.debug("Using subjectDN: " + subjectDNName.toString());
    }
    certgen.setSubjectDN(subjectDNName);
    // We must take the issuer DN directly from the CA-certificate otherwise we risk re-ordering the DN
    // which many applications do not like.
    if (isRootCA) {
        // This will be an initial root CA, since no CA-certificate exists
        // Or it is a root CA, since the cert is self signed. If it is a root CA we want to use the same encoding for subject and issuer,
        // it might have changed over the years.
        if (log.isDebugEnabled()) {
            log.debug("Using subject DN also as issuer DN, because it is a root CA");
        }
        certgen.setIssuerDN(subjectDNName);
    } else {
        javax.security.auth.x500.X500Principal issuerPrincipal = cacert.getSubjectX500Principal();
        if (log.isDebugEnabled()) {
            log.debug("Using issuer DN directly from the CA certificate: " + issuerPrincipal.getName());
        }
        certgen.setIssuerDN(issuerPrincipal);
    }
    certgen.setPublicKey(publicKey);

    //
    // X509 Certificate Extensions
    //

    // Extensions we will add to the certificate, later when we have filled the structure with 
    // everything we want.
    X509ExtensionsGenerator extgen = new X509ExtensionsGenerator();

    // First we check if there is general extension override, and add all extensions from 
    // the request in that case
    if (certProfile.getAllowExtensionOverride() && extensions != null) {
        Enumeration en = extensions.oids();
        while (en != null && en.hasMoreElements()) {
            DERObjectIdentifier oid = (DERObjectIdentifier) en.nextElement();
            X509Extension ext = extensions.getExtension(oid);
            if (log.isDebugEnabled()) {
                log.debug("Overriding extension with oid: " + oid);
            }
            extgen.addExtension(oid, ext.isCritical(), ext.getValue().getOctets());
        }
    }

    // Second we see if there is Key usage override
    X509Extensions overridenexts = extgen.generate();
    if (certProfile.getAllowKeyUsageOverride() && (keyusage >= 0)) {
        if (log.isDebugEnabled()) {
            log.debug("AllowKeyUsageOverride=true. Using KeyUsage from parameter: " + keyusage);
        }
        if ((certProfile.getUseKeyUsage() == true) && (keyusage >= 0)) {
            X509KeyUsage ku = new X509KeyUsage(keyusage);
            // We don't want to try to add custom extensions with the same oid if we have already added them 
            // from the request, if AllowExtensionOverride is enabled.
            // Two extensions with the same oid is not allowed in the standard.
            if (overridenexts.getExtension(X509Extensions.KeyUsage) == null) {
                extgen.addExtension(X509Extensions.KeyUsage, certProfile.getKeyUsageCritical(), ku);
            } else {
                if (log.isDebugEnabled()) {
                    log.debug(
                            "KeyUsage was already overridden by an extension, not using KeyUsage from parameter.");
                }
            }
        }
    }

    // Third, check for standard Certificate Extensions that should be added.
    // Standard certificate extensions are defined in CertificateProfile and CertificateExtensionFactory
    // and implemented in package org.ejbca.core.model.certextensions.standard
    CertificateExtensionFactory fact = CertificateExtensionFactory.getInstance();
    List<String> usedStdCertExt = certProfile.getUsedStandardCertificateExtensions();
    Iterator<String> certStdExtIter = usedStdCertExt.iterator();
    overridenexts = extgen.generate();
    while (certStdExtIter.hasNext()) {
        String oid = certStdExtIter.next();
        // We don't want to try to add standard extensions with the same oid if we have already added them 
        // from the request, if AllowExtensionOverride is enabled.
        // Two extensions with the same oid is not allowed in the standard.
        if (overridenexts.getExtension(new DERObjectIdentifier(oid)) == null) {
            CertificateExtension certExt = fact.getStandardCertificateExtension(oid, certProfile);
            if (certExt != null) {
                byte[] value = certExt.getValueEncoded(subject, this, certProfile, publicKey, caPublicKey);
                if (value != null) {
                    extgen.addExtension(new DERObjectIdentifier(certExt.getOID()), certExt.isCriticalFlag(),
                            value);
                }
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Extension with oid " + oid
                        + " has been overridden, standard extension will not be added.");
            }
        }
    }

    // Fourth, check for custom Certificate Extensions that should be added.
    // Custom certificate extensions is defined in certextensions.properties
    fact = CertificateExtensionFactory.getInstance();
    List<Integer> usedCertExt = certProfile.getUsedCertificateExtensions();
    Iterator<Integer> certExtIter = usedCertExt.iterator();
    while (certExtIter.hasNext()) {
        Integer id = certExtIter.next();
        CertificateExtension certExt = fact.getCertificateExtensions(id);
        if (certExt != null) {
            // We don't want to try to add custom extensions with the same oid if we have already added them 
            // from the request, if AllowExtensionOverride is enabled.
            // Two extensions with the same oid is not allowed in the standard.
            if (overridenexts.getExtension(new DERObjectIdentifier(certExt.getOID())) == null) {
                byte[] value = certExt.getValueEncoded(subject, this, certProfile, publicKey, caPublicKey);
                if (value != null) {
                    extgen.addExtension(new DERObjectIdentifier(certExt.getOID()), certExt.isCriticalFlag(),
                            value);
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("Extension with oid " + certExt.getOID()
                            + " has been overridden, custom extension will not be added.");
                }
            }
        }
    }

    // Finally add extensions to certificate generator
    X509Extensions exts = extgen.generate();
    Enumeration en = exts.oids();
    while (en.hasMoreElements()) {
        DERObjectIdentifier oid = (DERObjectIdentifier) en.nextElement();
        X509Extension ext = exts.getExtension(oid);
        certgen.addExtension(oid, ext.isCritical(), ext.getValue().getOctets());
    }

    //
    // End of extensions
    //

    X509Certificate cert;
    if (log.isTraceEnabled()) {
        log.trace(">certgen.generate");
    }
    cert = certgen.generate(caPrivateKey, provider);
    if (log.isTraceEnabled()) {
        log.trace("<certgen.generate");
    }

    // Verify using the CA certificate before returning
    // If we can not verify the issued certificate using the CA certificate we don't want to issue this cert
    // because something is wrong...
    PublicKey verifyKey;
    // We must use the configured public key if this is a rootCA, because then we can renew our own certificate, after changing
    // the keys. In this case the _new_ key will not match the current CA certificate.
    if ((cacert != null) && (!isRootCA)) {
        verifyKey = cacert.getPublicKey();
    } else {
        verifyKey = caPublicKey;
    }
    cert.verify(verifyKey);

    // If we have a CA-certificate, verify that we have all path verification stuff correct
    if (cacert != null) {
        byte[] aki = CertTools.getAuthorityKeyId(cert);
        byte[] ski = CertTools.getSubjectKeyId(isRootCA ? cert : cacert);
        if ((aki != null) && (ski != null)) {
            boolean eq = Arrays.equals(aki, ski);
            if (!eq) {
                String akistr = new String(Hex.encode(aki));
                String skistr = new String(Hex.encode(ski));
                log.error(intres.getLocalizedMessage("signsession.errorpathverifykeyid", akistr, skistr));
            }
        }
        Principal issuerDN = cert.getIssuerX500Principal();
        Principal subjectDN = cacert.getSubjectX500Principal();
        if ((issuerDN != null) && (subjectDN != null)) {
            boolean eq = issuerDN.equals(subjectDN);
            if (!eq) {
                log.error(intres.getLocalizedMessage("signsession.errorpathverifydn", issuerDN.getName(),
                        subjectDN.getName()));
            }
        }
    }
    if (log.isDebugEnabled()) {
        log.debug("X509CA: generated certificate, CA " + this.getCAId() + " for DN: "
                + subject.getCertificateDN());
    }
    return cert;
}

From source file:org.ejbca.core.protocol.ocsp.OCSPUtil.java

License:Open Source License

public static BasicOCSPRespGenerator createOCSPResponse(OCSPReq req, X509Certificate respondercert,
        int respIdType) throws OCSPException, NotSupportedException {
    if (null == req) {
        throw new IllegalArgumentException();
    }//from   ww  w  . jav a  2  s . c o  m
    BasicOCSPRespGenerator res = null;
    if (respIdType == OcspConfiguration.RESPONDERIDTYPE_NAME) {
        res = new BasicOCSPRespGenerator(new RespID(respondercert.getSubjectX500Principal()));
    } else {
        res = new BasicOCSPRespGenerator(respondercert.getPublicKey());
    }
    X509Extensions reqexts = req.getRequestExtensions();
    if (reqexts != null) {
        X509Extension ext = reqexts.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_response);
        if (null != ext) {
            //m_log.debug("Found extension AcceptableResponses");
            ASN1OctetString oct = ext.getValue();
            try {
                ASN1Sequence seq = ASN1Sequence.getInstance(
                        new ASN1InputStream(new ByteArrayInputStream(oct.getOctets())).readObject());
                Enumeration en = seq.getObjects();
                boolean supportsResponseType = false;
                while (en.hasMoreElements()) {
                    DERObjectIdentifier oid = (DERObjectIdentifier) en.nextElement();
                    //m_log.debug("Found oid: "+oid.getId());
                    if (oid.equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic)) {
                        // This is the response type we support, so we are happy! Break the loop.
                        supportsResponseType = true;
                        m_log.debug("Response type supported: " + oid.getId());
                        continue;
                    }
                }
                if (!supportsResponseType) {
                    throw new NotSupportedException(
                            "Required response type not supported, this responder only supports id-pkix-ocsp-basic.");
                }
            } catch (IOException e) {
            }
        }
    }
    return res;
}

From source file:org.ejbca.core.protocol.ocsp.OCSPUtil.java

License:Open Source License

/** returns an HashTable of responseExtensions to be added to the BacisOCSPResponseGenerator with
 * <code>//  ww w . j  a  v a2s . c o m
 * X509Extensions exts = new X509Extensions(table);
 * basicRes.setResponseExtensions(responseExtensions);
 * </code>
 * 
 * @param req OCSPReq
 * @return a Hashtable, can be empty nut not null
 */
public static Hashtable getStandardResponseExtensions(OCSPReq req) {
    X509Extensions reqexts = req.getRequestExtensions();
    Hashtable table = new Hashtable();
    if (reqexts != null) {
        // Table of extensions to include in the response
        X509Extension ext = reqexts.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
        if (null != ext) {
            //m_log.debug("Found extension Nonce");
            table.put(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, ext);
        }
    }
    return table;
}

From source file:org.ejbca.core.protocol.PKCS10RequestMessage.java

License:Open Source License

/**
 * Returns the challenge password from the certificattion request.
 *
 * @return challenge password from certification request or null if none exist in the request.
 *///from  w ww.  jav a  2s . c o m
public String getPassword() {
    if (password != null) {
        return password;
    }
    try {
        if (pkcs10 == null) {
            init();
        }
    } catch (IllegalArgumentException e) {
        log.error("PKCS10 not inited!");
        return null;
    }

    String ret = null;

    // Get attributes
    // The password attribute can be either a pkcs_9_at_challengePassword directly
    // or
    // a pkcs_9_at_extensionRequest containing a pkcs_9_at_challengePassword as a
    // X509Extension.
    AttributeTable attributes = null;
    CertificationRequestInfo info = pkcs10.getCertificationRequestInfo();
    if (info != null) {
        ASN1Set attrs = info.getAttributes();
        if (attrs != null) {
            attributes = new AttributeTable(attrs);
        }
    }
    if (attributes == null) {
        return null;
    }
    Attribute attr = attributes.get(PKCSObjectIdentifiers.pkcs_9_at_challengePassword);
    DEREncodable obj = null;
    if (attr == null) {
        // See if we have it embedded in an extension request instead
        attr = attributes.get(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
        if (attr == null) {
            return null;
        }
        if (log.isDebugEnabled()) {
            log.debug("got extension request");
        }
        ASN1Set values = attr.getAttrValues();
        if (values.size() == 0) {
            return null;
        }
        X509Extensions exts = X509Extensions.getInstance(values.getObjectAt(0));
        X509Extension ext = exts.getExtension(PKCSObjectIdentifiers.pkcs_9_at_challengePassword);
        if (ext == null) {
            if (log.isDebugEnabled()) {
                log.debug("no challenge password extension");
            }
            return null;
        }
        obj = ext.getValue();
    } else {
        // If it is a challengePassword directly, it's just to grab the value
        ASN1Set values = attr.getAttrValues();
        obj = values.getObjectAt(0);
    }

    if (obj != null) {
        DERString str = null;

        try {
            str = DERPrintableString.getInstance((obj));
        } catch (IllegalArgumentException ie) {
            // This was not printable string, should be utf8string then according to pkcs#9 v2.0
            str = DERUTF8String.getInstance((obj));
        }

        if (str != null) {
            ret = str.getString();
        }
    }

    return ret;
}

From source file:org.ejbca.core.protocol.PKCS10RequestMessage.java

License:Open Source License

public String getRequestAltNames() {
    String ret = null;/*from w w  w .ja  v a 2s. com*/
    try {
        X509Extensions exts = getRequestExtensions();
        if (exts != null) {
            X509Extension ext = exts.getExtension(X509Extensions.SubjectAlternativeName);
            if (ext != null) {
                // Finally read the value
                ret = CertTools.getAltNameStringFromExtension(ext);
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("no subject altName extension");
                }
            }
        }
    } catch (IllegalArgumentException e) {
        if (log.isDebugEnabled()) {
            log.debug(
                    "pkcs_9_extensionRequest does not contain Extensions that it should, ignoring invalid encoded extension request.");
        }
    }
    return ret;
}