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.ejbca.ui.web.protocol.OCSPServletBase.java

License:Open Source License

/** Performs service of the actual OCSP request, which is contained in reqBytes. 
 *  /*w  w  w.  j  a v a  2  s .  c o m*/
 *  @param reqBytes the binary OCSP request bytes. This parameter must already have been checked for max or min size. 
 */
public void serviceOCSP(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
    if (m_log.isTraceEnabled()) {
        m_log.trace(">service()");
    }
    final int localTransactionID;
    synchronized (this) {
        this.mTransactionID += 1;
        localTransactionID = this.mTransactionID;
    }
    final IPatternLogger transactionLogger;
    final IPatternLogger auditLogger;
    final Date startTime = new Date();
    if (this.mDoTransactionLog) {
        transactionLogger = this.transactionLogger.getPatternLogger();
    } else {
        transactionLogger = new DummyPatternLogger(); // Ignores everything
    }
    if (this.mDoAuditLog) {
        auditLogger = this.auditLogger.getPatternLogger();
    } else {
        auditLogger = new DummyPatternLogger(); // Ignores everything
    }
    final String remoteAddress = request.getRemoteAddr();
    auditLogger.paramPut(IAuditLogger.OCSPREQUEST, ""); // No request bytes yet
    auditLogger.paramPut(IPatternLogger.LOG_ID, new Integer(localTransactionID));
    auditLogger.paramPut(IPatternLogger.SESSION_ID, this.m_SessionID);
    auditLogger.paramPut(IOCSPLogger.CLIENT_IP, remoteAddress);
    transactionLogger.paramPut(IPatternLogger.LOG_ID, new Integer(localTransactionID));
    transactionLogger.paramPut(IPatternLogger.SESSION_ID, this.m_SessionID);
    transactionLogger.paramPut(IOCSPLogger.CLIENT_IP, remoteAddress);

    try {
        // Read configuration values affecting the response, these can be dynamically updated from properties files in file system
        // Read default values here for each request since may take a millisecond to read the value
        // These values can be changed depending on if there are different configurations for different certificate profiles
        // In that case it is updated once we have read the certificate status of the certificate searched for.
        long maxAge = OcspConfiguration.getMaxAge(SecConst.CERTPROFILE_NO_PROFILE);
        long nextUpdate = OcspConfiguration.getUntilNextUpdate(SecConst.CERTPROFILE_NO_PROFILE);

        OCSPResp ocspresp = null;
        OCSPRespGenerator res = new OCSPRespGenerator();
        X509Certificate cacert = null; // CA-certificate used to sign response
        try {
            byte[] reqBytes = checkAndGetRequestBytes(request);
            // Start logging process time after we have received the request
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IAuditLogger.OCSPREQUEST, new String(Hex.encode(reqBytes)));
            OCSPReq req = null;
            try {
                req = new OCSPReq(reqBytes);
            } catch (Exception e) {
                // When not being able to parse the request, we want to send a MalformedRequest back
                throw new MalformedRequestException(e);
            }
            if (req.getRequestorName() == null) {
                m_log.debug("Requestorname is null");
            } else {
                if (m_log.isDebugEnabled()) {
                    m_log.debug("Requestorname is: " + req.getRequestorName().toString());
                }
                transactionLogger.paramPut(ITransactionLogger.REQ_NAME, req.getRequestorName().toString());
            }
            // Make sure our signature keys are updated
            loadPrivateKeys(this.data.m_adm, null);

            /**
             * check the signature if contained in request.
             * if the request does not contain a signature
             * and the servlet is configured in the way 
             * the a signature is required we send back
             * 'sigRequired' response.
             */
            if (m_log.isDebugEnabled()) {
                m_log.debug("Incoming OCSP request is signed : " + req.isSigned());
            }
            if (req.isSigned()) {
                X509Certificate signercert = OCSPUtil.checkRequestSignature(request.getRemoteAddr(), req,
                        this.data.m_caCertCache);
                String signercertIssuerName = CertTools.getIssuerDN(signercert);
                BigInteger signercertSerNo = CertTools.getSerialNumber(signercert);
                String signercertSubjectName = CertTools.getSubjectDN(signercert);
                transactionLogger.paramPut(ITransactionLogger.SIGN_ISSUER_NAME_DN, signercertIssuerName);
                transactionLogger.paramPut(ITransactionLogger.SIGN_SERIAL_NO,
                        signercert.getSerialNumber().toByteArray());
                transactionLogger.paramPut(ITransactionLogger.SIGN_SUBJECT_NAME, signercertSubjectName);
                transactionLogger.paramPut(IPatternLogger.REPLY_TIME, ITransactionLogger.REPLY_TIME);
                if (OcspConfiguration.getEnforceRequestSigning()) {
                    // If it verifies OK, check if it is revoked
                    final CertificateStatus status = this.data.certificateStoreSession.getStatus(
                            CertTools.getIssuerDN(signercert), CertTools.getSerialNumber(signercert));
                    // If rci == null it means the certificate does not exist in database, we then treat it as ok,
                    // because it may be so that only revoked certificates is in the (external) OCSP database.
                    if (status.equals(CertificateStatus.REVOKED)) {
                        String serno = signercertSerNo.toString(16);
                        String infoMsg = intres.getLocalizedMessage("ocsp.infosigner.revoked",
                                signercertSubjectName, signercertIssuerName, serno);
                        m_log.info(infoMsg);
                        throw new SignRequestSignatureException(infoMsg);
                    }

                    if (m_reqRestrictSignatures) {
                        loadTrustDir();
                        if (m_reqRestrictMethod == OcspConfiguration.RESTRICTONSIGNER) {
                            if (!OCSPUtil.checkCertInList(signercert, mTrustedReqSigSigners)) {
                                String infoMsg = intres.getLocalizedMessage("ocsp.infosigner.notallowed",
                                        signercertSubjectName, signercertIssuerName,
                                        signercertSerNo.toString(16));
                                m_log.info(infoMsg);
                                throw new SignRequestSignatureException(infoMsg);
                            }
                        } else if (m_reqRestrictMethod == OcspConfiguration.RESTRICTONISSUER) {
                            X509Certificate signerca = this.data.m_caCertCache
                                    .findLatestBySubjectDN(HashID.getFromDN(signercertIssuerName));
                            if ((signerca == null)
                                    || (!OCSPUtil.checkCertInList(signerca, mTrustedReqSigIssuers))) {
                                String infoMsg = intres.getLocalizedMessage("ocsp.infosigner.notallowed",
                                        signercertSubjectName, signercertIssuerName,
                                        signercertSerNo.toString(16));
                                m_log.info(infoMsg);
                                throw new SignRequestSignatureException(infoMsg);
                            }
                        } else {
                            throw new Exception("m_reqRestrictMethod=" + m_reqRestrictMethod); // there must be an internal error. We do not want to send a response, just to be safe.
                        }
                    }
                }
            } else {
                if (OcspConfiguration.getEnforceRequestSigning()) {
                    // Signature required
                    throw new SignRequestException("Signature required");
                }
            }

            // Get the certificate status requests that are inside this OCSP req
            Req[] requests = req.getRequestList();
            transactionLogger.paramPut(ITransactionLogger.NUM_CERT_ID, requests.length);
            if (requests.length <= 0) {
                String infoMsg = intres.getLocalizedMessage("ocsp.errornoreqentities");
                m_log.info(infoMsg);
                {
                    // All this just so we can create an error response
                    cacert = this.data.m_caCertCache
                            .findLatestBySubjectDN(HashID.getFromDN(this.data.m_defaultResponderId));
                }
                throw new MalformedRequestException(infoMsg);
            }
            int maxRequests = 100;
            if (requests.length > maxRequests) {
                String infoMsg = intres.getLocalizedMessage("ocsp.errortoomanyreqentities", maxRequests);
                m_log.info(infoMsg);
                {
                    // All this just so we can create an error response
                    cacert = this.data.m_caCertCache
                            .findLatestBySubjectDN(HashID.getFromDN(this.data.m_defaultResponderId));
                }
                throw new MalformedRequestException(infoMsg);
            }

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

            // Add standard response extensions
            Hashtable responseExtensions = OCSPUtil.getStandardResponseExtensions(req);
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
            // Look over the status requests
            ArrayList responseList = new ArrayList();
            for (int i = 0; i < requests.length; i++) {
                CertificateID certId = requests[i].getCertID();
                // now some Logging
                transactionLogger.paramPut(ITransactionLogger.SERIAL_NOHEX,
                        certId.getSerialNumber().toByteArray());
                transactionLogger.paramPut(ITransactionLogger.DIGEST_ALGOR, certId.getHashAlgOID()); //todo, find text version of this or find out if it should be something else               
                transactionLogger.paramPut(ITransactionLogger.ISSUER_NAME_HASH, certId.getIssuerNameHash());
                transactionLogger.paramPut(ITransactionLogger.ISSUER_KEY, certId.getIssuerKeyHash());
                auditLogger.paramPut(IAuditLogger.ISSUER_KEY, certId.getIssuerKeyHash());
                auditLogger.paramPut(IAuditLogger.SERIAL_NOHEX, certId.getSerialNumber().toByteArray());
                auditLogger.paramPut(IAuditLogger.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, request.getRemoteAddr());
                m_log.info(infoMsg);
                boolean unknownCA = false;
                // if the certId was issued by an unknown CA
                // The algorithm here:
                // We will sign the response with the CA that issued the first 
                // 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. 
                cacert = this.data.m_caCertCache.findByOcspHash(certId); // Get the issuer of certId
                if (cacert == null) {
                    // We could not find certificate for this request so get certificate for default responder
                    cacert = this.data.m_caCertCache
                            .findLatestBySubjectDN(HashID.getFromDN(this.data.m_defaultResponderId));
                    unknownCA = true;
                }
                if (cacert == null) {
                    String errMsg = intres.getLocalizedMessage("ocsp.errorfindcacert",
                            new String(Hex.encode(certId.getIssuerNameHash())), this.data.m_defaultResponderId);
                    m_log.error(errMsg);
                    continue;
                }
                if (unknownCA == true) {
                    String errMsg = intres.getLocalizedMessage("ocsp.errorfindcacertusedefault",
                            new String(Hex.encode(certId.getIssuerNameHash())));
                    m_log.info(errMsg);
                    // If we can not find the CA, answer UnknowStatus
                    responseList.add(new OCSPResponseItem(certId, new UnknownStatus(), nextUpdate));
                    transactionLogger.paramPut(ITransactionLogger.CERT_STATUS, OCSPUnidResponse.OCSP_UNKNOWN);
                    transactionLogger.writeln();
                    continue;
                } else {
                    transactionLogger.paramPut(ITransactionLogger.ISSUER_NAME_DN,
                            cacert.getSubjectDN().getName());
                }
                /*
                 * 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(ITransactionLogger.CERT_STATUS, OCSPUnidResponse.OCSP_GOOD); // it seems to be correct
                // Check if the cacert (or the default responderid) is revoked
                final CertificateStatus cacertStatus = this.data.certificateStoreSession
                        .getStatus(CertTools.getIssuerDN(cacert), CertTools.getSerialNumber(cacert));
                if (!cacertStatus.equals(CertificateStatus.REVOKED)) {
                    // Check if cert is revoked
                    final CertificateStatus status = this.data.certificateStoreSession
                            .getStatus(cacert.getSubjectDN().getName(), 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 (m_log.isDebugEnabled()) {
                        m_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 (m_log.isDebugEnabled()) {
                            m_log.debug("Unable to find revocation information for certificate with serial '"
                                    + certId.getSerialNumber().toString(16) + "'" + " from issuer '"
                                    + cacert.getSubjectDN().getName() + "'");
                        }
                        // 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 (!nonExistingIsGood(request.getRequestURL())
                                || this.data.m_caCertCache.findByOcspHash(certId) == null) {
                            sStatus = "unknown";
                            certStatus = new UnknownStatus();
                            transactionLogger.paramPut(ITransactionLogger.CERT_STATUS,
                                    OCSPUnidResponse.OCSP_UNKNOWN);
                        } else {
                            sStatus = "good";
                            certStatus = null; // null means "good" in OCSP
                            transactionLogger.paramPut(ITransactionLogger.CERT_STATUS,
                                    OCSPUnidResponse.OCSP_GOOD);
                        }
                    } 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)));
                        transactionLogger.paramPut(ITransactionLogger.CERT_STATUS,
                                OCSPUnidResponse.OCSP_REVOKED); //1 = revoked
                    } else {
                        sStatus = "good";
                        certStatus = null;
                        transactionLogger.paramPut(ITransactionLogger.CERT_STATUS, OCSPUnidResponse.OCSP_GOOD);
                    }
                    infoMsg = intres.getLocalizedMessage("ocsp.infoaddedstatusinfo", sStatus,
                            certId.getSerialNumber().toString(16), cacert.getSubjectDN().getName());
                    m_log.info(infoMsg);
                    responseList.add(new OCSPResponseItem(certId, certStatus, nextUpdate));
                    transactionLogger.writeln();
                } else {
                    certStatus = new RevokedStatus(
                            new RevokedInfo(new DERGeneralizedTime(cacertStatus.revocationDate),
                                    new CRLReason(cacertStatus.revocationReason)));
                    infoMsg = intres.getLocalizedMessage("ocsp.infoaddedstatusinfo", "revoked",
                            certId.getSerialNumber().toString(16), cacert.getSubjectDN().getName());
                    m_log.info(infoMsg);
                    responseList.add(new OCSPResponseItem(certId, certStatus, nextUpdate));
                    transactionLogger.paramPut(ITransactionLogger.CERT_STATUS, OCSPUnidResponse.OCSP_REVOKED);
                    transactionLogger.writeln();
                }
                // Look for extension OIDs
                Iterator iter = m_extensionOids.iterator();
                while (iter.hasNext()) {
                    String oidstr = (String) iter.next();
                    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 extenstion class
                            if (m_log.isDebugEnabled()) {
                                m_log.debug("Found OCSP extension oid: " + oidstr);
                            }
                            IOCSPExtension extObj = (IOCSPExtension) m_extensionMap.get(oidstr);
                            if (extObj != null) {
                                // Find the certificate from the certId
                                X509Certificate cert = null;
                                cert = (X509Certificate) this.data.certificateStoreSession
                                        .findCertificateByIssuerAndSerno(this.data.m_adm,
                                                cacert.getSubjectDN().getName(), certId.getSerialNumber());
                                if (cert != null) {
                                    // Call the OCSP extension
                                    Hashtable retext = extObj.process(request, 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(),
                                                new Integer(extObj.getLastErrorCode()));
                                        m_log.error(errMsg);
                                    }
                                }
                            }
                        }
                    }
                }
            } // end of huge for loop
            if (cacert != null) {
                // Add responseExtensions
                X509Extensions exts = new X509Extensions(responseExtensions);
                // generate the signed response object
                BasicOCSPResp basicresp = signOCSPResponse(req, responseList, exts, cacert);
                ocspresp = res.generate(OCSPRespGenerator.SUCCESSFUL, basicresp);
                auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
                transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
            } else {
                // Only unknown CAs in requests and no default reponders cert 
                String errMsg = intres.getLocalizedMessage("ocsp.errornocacreateresp");
                m_log.error(errMsg);
                throw new ServletException(errMsg);
            }
        } catch (MalformedRequestException e) {
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            m_log.info(errMsg);
            if (m_log.isDebugEnabled()) {
                m_log.debug(errMsg, e);
            }
            ocspresp = res.generate(OCSPRespGenerator.MALFORMED_REQUEST, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.MALFORMED_REQUEST);
            transactionLogger.writeln();
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.MALFORMED_REQUEST);
        } catch (SignRequestException e) {
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            m_log.info(errMsg); // No need to log the full exception here
            ocspresp = res.generate(OCSPRespGenerator.SIG_REQUIRED, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.SIG_REQUIRED);
            transactionLogger.writeln();
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.SIG_REQUIRED);
        } catch (SignRequestSignatureException e) {
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            m_log.info(errMsg); // No need to log the full exception here
            ocspresp = res.generate(OCSPRespGenerator.UNAUTHORIZED, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
            transactionLogger.writeln();
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
        } catch (InvalidKeyException e) {
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            m_log.info(errMsg, e);
            ocspresp = res.generate(OCSPRespGenerator.UNAUTHORIZED, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
            transactionLogger.writeln();
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
        } catch (Throwable e) {
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            m_log.error(errMsg, e);
            ocspresp = res.generate(OCSPRespGenerator.INTERNAL_ERROR, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.INTERNAL_ERROR);
            transactionLogger.writeln();
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.INTERNAL_ERROR);
        }
        byte[] respBytes = ocspresp.getEncoded();
        auditLogger.paramPut(IAuditLogger.OCSPRESPONSE, new String(Hex.encode(respBytes)));
        auditLogger.writeln();
        auditLogger.flush();
        transactionLogger.flush();
        if (mDoSaferLogging) {
            // See if the Errorhandler has found any problems
            if (hasErrorHandlerFailedSince(startTime)) {
                m_log.info("ProbableErrorhandler reported error, cannot answer request");
                ocspresp = res.generate(OCSPRespGenerator.INTERNAL_ERROR, null); // RFC 2560: responseBytes are not set on error.
                respBytes = ocspresp.getEncoded();
            }
            // See if the Appender has reported any problems
            if (!canlog) {
                m_log.info("SaferDailyRollingFileAppender reported error, cannot answer request");
                ocspresp = res.generate(OCSPRespGenerator.INTERNAL_ERROR, null); // RFC 2560: responseBytes are not set on error.
                respBytes = ocspresp.getEncoded();
            }
        }
        response.setContentType("application/ocsp-response");
        //response.setHeader("Content-transfer-encoding", "binary");
        response.setContentLength(respBytes.length);
        addRfc5019CacheHeaders(request, response, ocspresp, maxAge);
        response.getOutputStream().write(respBytes);
        response.getOutputStream().flush();
    } catch (OCSPException e) {
        String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
        m_log.error(errMsg, e);
        throw new ServletException(e);
    } catch (Exception e) {
        m_log.error("", e);
        transactionLogger.flush();
        auditLogger.flush();
    }
    if (m_log.isTraceEnabled()) {
        m_log.trace("<service()");
    }
}

From source file:org.ejbca.util.CertToolsTest.java

License:Open Source License

@SuppressWarnings("unchecked")
public void test19getAltNameStringFromExtension() throws Exception {
    PKCS10CertificationRequest p10 = new PKCS10CertificationRequest(p10ReqWithAltNames);
    CertificationRequestInfo info = p10.getCertificationRequestInfo();
    ASN1Set set = info.getAttributes();
    // The set of attributes contains a sequence of with type oid
    // PKCSObjectIdentifiers.pkcs_9_at_extensionRequest
    Enumeration<Object> en = set.getObjects();
    boolean found = false;
    while (en.hasMoreElements()) {
        ASN1Sequence seq = ASN1Sequence.getInstance(en.nextElement());
        DERObjectIdentifier oid = (DERObjectIdentifier) seq.getObjectAt(0);
        if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) {
            // The object at position 1 is a SET of x509extensions
            DERSet s = (DERSet) seq.getObjectAt(1);
            X509Extensions exts = X509Extensions.getInstance(s.getObjectAt(0));
            X509Extension ext = exts.getExtension(X509Extensions.SubjectAlternativeName);
            if (ext != null) {
                found = true;// ww w.jav a  2 s  . co  m
                String altNames = CertTools.getAltNameStringFromExtension(ext);
                assertEquals("dNSName=ort3-kru.net.polisen.se, iPAddress=10.252.255.237", altNames);
            }
        }
    }
    assertTrue(found);

    p10 = new PKCS10CertificationRequest(p10ReqWithAltNames2);
    info = p10.getCertificationRequestInfo();
    set = info.getAttributes();
    // The set of attributes contains a sequence of with type oid
    // PKCSObjectIdentifiers.pkcs_9_at_extensionRequest

    en = set.getObjects();
    found = false;
    while (en.hasMoreElements()) {
        ASN1Sequence seq = ASN1Sequence.getInstance(en.nextElement());
        DERObjectIdentifier oid = (DERObjectIdentifier) seq.getObjectAt(0);
        if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) {
            // The object at position 1 is a SET of x509extensions
            DERSet s = (DERSet) seq.getObjectAt(1);
            X509Extensions exts = X509Extensions.getInstance(s.getObjectAt(0));
            X509Extension ext = exts.getExtension(X509Extensions.SubjectAlternativeName);
            if (ext != null) {
                found = true;
                String altNames = CertTools.getAltNameStringFromExtension(ext);
                assertEquals("dNSName=foo.bar.com, iPAddress=10.0.0.1", altNames);
            }
        }
    }
    assertTrue(found);

}

From source file:org.glite.slcs.pki.CertificateRequest.java

License:eu-egee.org license

/**
 * Returns a List of certificate extensions contained in the certificate
 * request./*from  w w w .j  a va2  s  .  c  o  m*/
 * 
 * @return The List of CertificateExtension
 */
public List getCertificateExtensions() {
    List certificateExtensions = new ArrayList();
    X509Extensions x509Extensions = pkcs10_.getX509Extensions();
    if (x509Extensions != null) {
        Enumeration oids = x509Extensions.oids();
        while (oids.hasMoreElements()) {
            DERObjectIdentifier oid = (DERObjectIdentifier) oids.nextElement();
            X509Extension x509Extension = x509Extensions.getExtension(oid);
            boolean critical = x509Extension.isCritical();
            CertificateExtension extension = new CertificateExtension(oid, x509Extension, critical);
            certificateExtensions.add(extension);
        }
    }
    return certificateExtensions;
}

From source file:org.glite.voms.PKIVerifier.java

License:Open Source License

/**
 * Verifies an Attribute Certificate according to RFC 3281.
 * //  w ww .ja  v a2s .  c o m
 * @param ac
 *            the Attribute Certificate to verify.
 * 
 * @return true if the attribute certificate is verified, false otherwise.
 */
public boolean verify(AttributeCertificate ac) {

    if (ac == null || vomsStore == null)
        return false;

    AttributeCertificateInfo aci = ac.getAcinfo();
    X509Certificate[] certificates = null;

    ACCerts certList = aci.getCertList();

    LSCFile lsc = null;
    String voName = ac.getVO();

    if (certList != null)
        lsc = vomsStore.getLSC(voName, ac.getHost());

    logger.debug("LSC is: " + lsc);
    if (lsc != null) {
        boolean success = false;
        Vector dns = lsc.getDNLists();
        Iterator dnIter = dns.iterator();

        // First verify if LSC file applies;

        while (!success && dnIter.hasNext()) {
            boolean doBreak = false;

            while (dnIter.hasNext() && !doBreak) {
                Iterator certIter = certList.getCerts().iterator();
                Vector realDNs = (Vector) dnIter.next();
                Iterator realDNsIter = realDNs.iterator();

                while (realDNsIter.hasNext() && certIter.hasNext() && !doBreak) {
                    String dn = null;
                    String is = null;

                    try {
                        dn = (String) realDNsIter.next();
                        is = (String) realDNsIter.next();
                    } catch (NoSuchElementException e) {
                        doBreak = true;
                    }
                    X509Certificate cert = (X509Certificate) certIter.next();
                    String candidateDN = PKIUtils.getOpenSSLFormatPrincipal(cert.getSubjectDN());
                    String candidateIs = PKIUtils.getOpenSSLFormatPrincipal(cert.getIssuerDN());

                    logger.debug("dn is : " + dn);
                    logger.debug("is is : " + is);
                    logger.debug("canddn is : " + candidateDN);
                    logger.debug("candis is : " + candidateIs);
                    logger.debug("dn == canddn is " + dn.equals(candidateDN));
                    logger.debug("is == candis is " + is.equals(candidateIs));
                    if (!dn.equals(candidateDN) || !is.equals(candidateIs))
                        doBreak = true;
                }

                if (!doBreak && !realDNsIter.hasNext() && !certIter.hasNext())
                    success = true;
            }
        }

        if (success == true) {
            // LSC found. Now verifying certificate
            certificates = (X509Certificate[]) certList.getCerts().toArray(new X509Certificate[] {});
        }
    }

    if (certificates == null) {
        // lsc check failed
        logger.debug("lsc check failed.");
        // System.out.println("Looking for certificates.");
        if (logger.isDebugEnabled())
            logger.debug("Looking for hash: " + PKIUtils.getHash(ac.getIssuer()) + " for certificate: "
                    + ac.getIssuer().getName());

        X509Certificate[] candidates = vomsStore.getAACandidate(ac.getIssuer(), voName);

        if (candidates == null)
            logger.debug("No candidates found!");
        else if (candidates.length != 0) {
            int i = 0;
            while (i < candidates.length) {
                X509Certificate currentCert = (X509Certificate) candidates[i];
                PublicKey key = currentCert.getPublicKey();

                if (logger.isDebugEnabled()) {
                    logger.debug("Candidate: " + currentCert.getSubjectDN().getName());
                    logger.debug("Key class: " + key.getClass());
                    logger.debug("Key: " + key);
                    byte[] data = key.getEncoded();
                    String str = "Key: ";

                    for (int j = 0; j < data.length; j++)
                        str += Integer.toHexString(data[j]) + " ";

                    logger.debug(str);
                }

                if (ac.verifyCert(currentCert)) {
                    logger.debug("Signature Verification OK");

                    certificates = new X509Certificate[1];
                    certificates[0] = currentCert;
                    break;
                } else {
                    logger.debug("Signature Verification false");
                }
                i++;
            }
        }
    }

    if (certificates == null) {
        logger.error(
                "Cannot find usable certificates to validate the AC. Check that the voms server host certificate is in your vomsdir directory.");
        return false;
    }

    if (logger.isDebugEnabled()) {
        for (int l = 0; l < certificates.length; l++)
            logger.debug("Position: " + l + " value: " + certificates[l].getSubjectDN().getName());
    }

    if (!verify(certificates)) {
        logger.error("Cannot verify issuer certificate chain for AC");
        return false;
    }

    if (!ac.isValid()) {
        logger.error("Attribute Certificate not valid at current time.");
        return false;
    }

    // AC Targeting verification

    ACTargets targets = aci.getTargets();

    if (targets != null) {
        String hostname = getHostName();

        boolean success = false;
        Iterator i = targets.getTargets().iterator();

        while (i.hasNext()) {
            String name = (String) i.next();

            if (name.equals(hostname)) {
                success = true;
                break;
            }
        }
        if (!success) {
            logger.error("Targeting check failed!");
            return false;
        }
    }

    // unhandled extensions check
    X509Extensions exts = aci.getExtensions();

    if (exts != null) {
        Enumeration oids = exts.oids();
        while (oids.hasMoreElements()) {
            DERObjectIdentifier oid = (DERObjectIdentifier) oids.nextElement();
            X509Extension ext = exts.getExtension(oid);
            if (ext.isCritical() && !handledACOIDs.contains(oid)) {
                logger.error("Unknown critical extension discovered: " + oid.getId());
                return false;
            }
        }
    }
    return true;
}

From source file:org.globus.gsi.bc.BouncyCastleCertProcessingFactory.java

License:Apache License

/**
 * Creates a proxy certificate. A set of X.509 extensions can be optionally included in the new proxy
 * certificate. <BR>//from   w  ww  .  j ava  2 s .c  o m
 * If a GSI-2 proxy is created, the serial number of the proxy certificate will be the same as of the
 * issuing certificate. Also, none of the extensions in the issuing certificate will be copied into the
 * proxy certificate.<BR>
 * If a GSI-3 or GSI 4 proxy is created, the serial number of the proxy certificate will be picked
 * randomly. If the issuing certificate contains a <i>KeyUsage</i> extension, the extension will be copied
 * into the proxy certificate with <i>keyCertSign</i> and <i>nonRepudiation</i> bits turned off. No other
 * extensions are currently copied.
 *
 * The methods defaults to creating GSI 4 proxy
 *
 * @param issuerCert_
 *            the issuing certificate
 * @param issuerKey
 *            private key matching the public key of issuer certificate. The new proxy certificate will be
 *            signed by that key.
 * @param publicKey
 *            the public key of the new certificate
 * @param lifetime
 *            lifetime of the new certificate in seconds. If 0 (or less then) the new certificate will
 *            have the same lifetime as the issuing certificate.
 * @param proxyType
 *            can be one of {@link GSIConstants#DELEGATION_LIMITED GSIConstants.DELEGATION_LIMITED},
 *            {@link GSIConstants#DELEGATION_FULL GSIConstants.DELEGATION_FULL},
 *
 *            {@link GSIConstants#GSI_2_LIMITED_PROXY GSIConstants.GSI_2_LIMITED_PROXY},
 *            {@link GSIConstants#GSI_2_PROXY GSIConstants.GSI_2_PROXY},
 *            {@link GSIConstants#GSI_3_IMPERSONATION_PROXY GSIConstants.GSI_3_IMPERSONATION_PROXY},
 *            {@link GSIConstants#GSI_3_LIMITED_PROXY GSIConstants.GSI_3_LIMITED_PROXY},
 *            {@link GSIConstants#GSI_3_INDEPENDENT_PROXY GSIConstants.GSI_3_INDEPENDENT_PROXY},
 *            {@link GSIConstants#GSI_3_RESTRICTED_PROXY GSIConstants.GSI_3_RESTRICTED_PROXY}.
 *            {@link GSIConstants#GSI_4_IMPERSONATION_PROXY GSIConstants.GSI_4_IMPERSONATION_PROXY},
 *            {@link GSIConstants#GSI_4_LIMITED_PROXY GSIConstants.GSI_3_LIMITED_PROXY},
 *            {@link GSIConstants#GSI_4_INDEPENDENT_PROXY GSIConstants.GSI_4_INDEPENDENT_PROXY},
 *            {@link GSIConstants#GSI_4_RESTRICTED_PROXY GSIConstants.GSI_4_RESTRICTED_PROXY}.
 *
 *            If {@link GSIConstants#DELEGATION_LIMITED GSIConstants.DELEGATION_LIMITED} and if
 *            {@link VersionUtil#isGsi2Enabled() CertUtil.isGsi2Enabled} returns true then a GSI-2 limited
 *            proxy will be created. Else if {@link VersionUtil#isGsi3Enabled() CertUtil.isGsi3Enabled}
 *            returns true then a GSI-3 limited proxy will be created. If not, a GSI-4 limited proxy will
 *            be created.
 *
 *            If {@link GSIConstants#DELEGATION_FULL GSIConstants.DELEGATION_FULL} and if
 *            {@link VersionUtil#isGsi2Enabled() CertUtil.isGsi2Enabled} returns true then a GSI-2 full proxy
 *            will be created. Else if {@link VersionUtil#isGsi3Enabled() CertUtil.isGsi3Enabled} returns
 *            true then a GSI-3 full proxy will be created. If not, a GSI-4 full proxy will be created.
 *
 * @param extSet
 *            a set of X.509 extensions to be included in the new proxy certificate. Can be null. If
 *            delegation mode is {@link GSIConstants#GSI_3_RESTRICTED_PROXY
 *            GSIConstants.GSI_3_RESTRICTED_PROXY} or {@link GSIConstants#GSI_4_RESTRICTED_PROXY
 *            GSIConstants.GSI_4_RESTRICTED_PROXY} then
 *            {@link org.globus.gsi.proxy.ext.ProxyCertInfoExtension ProxyCertInfoExtension} must be
 *            present in the extension set.
 *
 * @param cnValue
 *            the value of the CN component of the subject of the new certificate. If null, the defaults
 *            will be used depending on the proxy certificate type created.
 * @return <code>X509Certificate</code> the new proxy certificate.
 * @exception GeneralSecurityException
 *                if a security error occurs.
 * @deprecated
 */
public X509Certificate createProxyCertificate(X509Certificate issuerCert_, PrivateKey issuerKey,
        PublicKey publicKey, int lifetime, int proxyType, X509ExtensionSet extSet, String cnValue)
        throws GeneralSecurityException {

    X509Certificate issuerCert = issuerCert_;
    if (!(issuerCert_ instanceof X509CertificateObject)) {
        issuerCert = CertificateLoadUtil.loadCertificate(new ByteArrayInputStream(issuerCert.getEncoded()));
    }

    if (proxyType == GSIConstants.DELEGATION_LIMITED) {
        GSIConstants.CertificateType type = BouncyCastleUtil.getCertificateType(issuerCert);
        if (ProxyCertificateUtil.isGsi4Proxy(type)) {
            proxyType = GSIConstants.GSI_4_LIMITED_PROXY;
        } else if (ProxyCertificateUtil.isGsi3Proxy(type)) {
            proxyType = GSIConstants.GSI_3_LIMITED_PROXY;
        } else if (ProxyCertificateUtil.isGsi2Proxy(type)) {
            proxyType = GSIConstants.GSI_2_LIMITED_PROXY;
        } else {
            // default to RFC compliant proxy
            if (VersionUtil.isGsi2Enabled()) {
                proxyType = GSIConstants.GSI_2_LIMITED_PROXY;
            } else {
                proxyType = VersionUtil.isGsi3Enabled() ? GSIConstants.GSI_3_LIMITED_PROXY
                        : GSIConstants.GSI_4_LIMITED_PROXY;
            }
        }
    } else if (proxyType == GSIConstants.DELEGATION_FULL) {
        GSIConstants.CertificateType type = BouncyCastleUtil.getCertificateType(issuerCert);
        if (ProxyCertificateUtil.isGsi4Proxy(type)) {
            proxyType = GSIConstants.GSI_4_IMPERSONATION_PROXY;
        } else if (ProxyCertificateUtil.isGsi3Proxy(type)) {
            proxyType = GSIConstants.GSI_3_IMPERSONATION_PROXY;
        } else if (ProxyCertificateUtil.isGsi2Proxy(type)) {
            proxyType = GSIConstants.GSI_2_PROXY;
        } else {
            // Default to RFC complaint proxy
            if (VersionUtil.isGsi2Enabled()) {
                proxyType = GSIConstants.GSI_2_PROXY;
            } else {
                proxyType = (VersionUtil.isGsi3Enabled()) ? GSIConstants.GSI_3_IMPERSONATION_PROXY
                        : GSIConstants.GSI_4_IMPERSONATION_PROXY;
            }
        }
    }

    X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

    org.globus.gsi.X509Extension x509Ext = null;
    BigInteger serialNum = null;
    String delegDN = null;

    if (ProxyCertificateUtil.isGsi3Proxy(GSIConstants.CertificateType.get(proxyType))
            || ProxyCertificateUtil.isGsi4Proxy(GSIConstants.CertificateType.get(proxyType))) {
        Random rand = new Random();
        delegDN = String.valueOf(Math.abs(rand.nextInt()));
        serialNum = new BigInteger(20, rand);

        if (extSet != null) {
            x509Ext = extSet.get(ProxyCertInfo.OID.getId());
            if (x509Ext == null) {
                x509Ext = extSet.get(ProxyCertInfo.OLD_OID.getId());
            }
        }

        if (x509Ext == null) {
            // create ProxyCertInfo extension
            ProxyPolicy policy = null;
            if (ProxyCertificateUtil.isLimitedProxy(GSIConstants.CertificateType.get(proxyType))) {
                policy = new ProxyPolicy(ProxyPolicy.LIMITED);
            } else if (ProxyCertificateUtil.isIndependentProxy(GSIConstants.CertificateType.get(proxyType))) {
                policy = new ProxyPolicy(ProxyPolicy.INDEPENDENT);
            } else if (ProxyCertificateUtil.isImpersonationProxy(GSIConstants.CertificateType.get(proxyType))) {
                // since limited has already been checked, this should work.
                policy = new ProxyPolicy(ProxyPolicy.IMPERSONATION);
            } else if ((proxyType == GSIConstants.GSI_3_RESTRICTED_PROXY)
                    || (proxyType == GSIConstants.GSI_4_RESTRICTED_PROXY)) {
                String err = i18n.getMessage("restrictProxy");
                throw new IllegalArgumentException(err);
            } else {
                String err = i18n.getMessage("invalidProxyType");
                throw new IllegalArgumentException(err);
            }

            ProxyCertInfo proxyCertInfo = new ProxyCertInfo(policy);
            x509Ext = new ProxyCertInfoExtension(proxyCertInfo);
            if (ProxyCertificateUtil.isGsi4Proxy(GSIConstants.CertificateType.get(proxyType))) {
                // RFC compliant OID
                x509Ext = new ProxyCertInfoExtension(proxyCertInfo);
            } else {
                // old OID
                x509Ext = new GlobusProxyCertInfoExtension(proxyCertInfo);
            }
        }

        try {
            // add ProxyCertInfo extension to the new cert
            certGen.addExtension(x509Ext.getOid(), x509Ext.isCritical(), x509Ext.getValue());

            // handle KeyUsage in issuer cert
            TBSCertificateStructure crt = BouncyCastleUtil.getTBSCertificateStructure(issuerCert);

            X509Extensions extensions = crt.getExtensions();
            if (extensions != null) {
                X509Extension ext;

                // handle key usage ext
                ext = extensions.getExtension(X509Extension.keyUsage);
                if (ext != null) {

                    // TBD: handle this better
                    if (extSet != null && (extSet.get(X509Extension.keyUsage.getId()) != null)) {
                        String err = i18n.getMessage("keyUsageExt");
                        throw new GeneralSecurityException(err);
                    }

                    DERBitString bits = (DERBitString) BouncyCastleUtil.getExtensionObject(ext);

                    byte[] bytes = bits.getBytes();

                    // make sure they are disabled
                    if ((bytes[0] & KeyUsage.nonRepudiation) != 0) {
                        bytes[0] ^= KeyUsage.nonRepudiation;
                    }

                    if ((bytes[0] & KeyUsage.keyCertSign) != 0) {
                        bytes[0] ^= KeyUsage.keyCertSign;
                    }

                    bits = new DERBitString(bytes, bits.getPadBits());

                    certGen.addExtension(X509Extension.keyUsage, ext.isCritical(), bits);
                }
            }

        } catch (IOException e) {
            // but this should not happen
            throw new GeneralSecurityException(e.getMessage());
        }

    } else if (proxyType == GSIConstants.GSI_2_LIMITED_PROXY) {
        delegDN = "limited proxy";
        serialNum = issuerCert.getSerialNumber();
    } else if (proxyType == GSIConstants.GSI_2_PROXY) {
        delegDN = "proxy";
        serialNum = issuerCert.getSerialNumber();
    } else {
        String err = i18n.getMessage("unsupportedProxy", Integer.toString(proxyType));
        throw new IllegalArgumentException(err);
    }

    // add specified extensions
    if (extSet != null) {
        Iterator iter = extSet.oidSet().iterator();
        while (iter.hasNext()) {
            String oid = (String) iter.next();
            // skip ProxyCertInfo extension
            if (oid.equals(ProxyCertInfo.OID.getId()) || oid.equals(ProxyCertInfo.OLD_OID.getId())) {
                continue;
            }
            x509Ext = (org.globus.gsi.X509Extension) extSet.get(oid);
            certGen.addExtension(x509Ext.getOid(), x509Ext.isCritical(), x509Ext.getValue());
        }
    }

    X509Name issuerDN;
    if (issuerCert.getSubjectDN() instanceof X509Name) {
        issuerDN = (X509Name) issuerCert.getSubjectDN();
    } else {
        issuerDN = new X509Name(true, issuerCert.getSubjectX500Principal().getName());
    }

    X509NameHelper issuer = new X509NameHelper(issuerDN);

    X509NameHelper subject = new X509NameHelper(issuerDN);
    subject.add(BCStyle.CN, (cnValue == null) ? delegDN : cnValue);

    certGen.setSubjectDN(subject.getAsName());
    certGen.setIssuerDN(issuer.getAsName());

    certGen.setSerialNumber(serialNum);
    certGen.setPublicKey(publicKey);
    certGen.setSignatureAlgorithm(issuerCert.getSigAlgName());

    GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    /* Allow for a five minute clock skew here. */
    date.add(Calendar.MINUTE, -5);
    certGen.setNotBefore(date.getTime());

    /* If hours = 0, then cert lifetime is set to user cert */
    if (lifetime <= 0) {
        certGen.setNotAfter(issuerCert.getNotAfter());
    } else {
        date.add(Calendar.MINUTE, 5);
        date.add(Calendar.SECOND, lifetime);
        certGen.setNotAfter(date.getTime());
    }

    return certGen.generateX509Certificate(issuerKey);
}

From source file:org.globus.gsi.bc.BouncyCastleCertProcessingFactory.java

License:Apache License

/**
 * Creates a proxy certificate. A set of X.509 extensions can be optionally included in the new proxy
 * certificate. <BR>//from w w  w .  j av  a2  s . c om
 * If a GSI-2 proxy is created, the serial number of the proxy certificate will be the same as of the
 * issuing certificate. Also, none of the extensions in the issuing certificate will be copied into the
 * proxy certificate.<BR>
 * If a GSI-3 or GSI 4 proxy is created, the serial number of the proxy certificate will be picked
 * randomly. If the issuing certificate contains a <i>KeyUsage</i> extension, the extension will be copied
 * into the proxy certificate with <i>keyCertSign</i> and <i>nonRepudiation</i> bits turned off. No other
 * extensions are currently copied.
 *
 * The methods defaults to creating GSI 4 proxy
 *
 * @param issuerCert_
 *            the issuing certificate
 * @param issuerKey
 *            private key matching the public key of issuer certificate. The new proxy certificate will be
 *            signed by that key.
 * @param publicKey
 *            the public key of the new certificate
 * @param lifetime
 *            lifetime of the new certificate in seconds. If 0 (or less then) the new certificate will
 *            have the same lifetime as the issuing certificate.
 * @param certType
 *            can be one of {@link org.globus.gsi.GSIConstants.CertificateType#GSI_2_LIMITED_PROXY GSIConstants.CertificateType.GSI_2_LIMITED_PROXY},
 *            {@link org.globus.gsi.GSIConstants.CertificateType#GSI_2_PROXY GSIConstants.CertificateType.GSI_2_PROXY},
 *            {@link org.globus.gsi.GSIConstants.CertificateType#GSI_3_IMPERSONATION_PROXY GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY},
 *            {@link org.globus.gsi.GSIConstants.CertificateType#GSI_3_LIMITED_PROXY GSIConstants.CertificateType.GSI_3_LIMITED_PROXY},
 *            {@link org.globus.gsi.GSIConstants.CertificateType#GSI_3_INDEPENDENT_PROXY GSIConstants.CertificateType.GSI_3_INDEPENDENT_PROXY},
 *            {@link org.globus.gsi.GSIConstants.CertificateType#GSI_3_RESTRICTED_PROXY GSIConstants.CertificateType.GSI_3_RESTRICTED_PROXY}.
 *            {@link org.globus.gsi.GSIConstants.CertificateType#GSI_4_IMPERSONATION_PROXY GSIConstants.CertificateType.GSI_4_IMPERSONATION_PROXY},
 *            {@link org.globus.gsi.GSIConstants.CertificateType#GSI_4_LIMITED_PROXY GSIConstants.CertificateType.GSI_3_LIMITED_PROXY},
 *            {@link org.globus.gsi.GSIConstants.CertificateType#GSI_4_INDEPENDENT_PROXY GSIConstants.CertificateType.GSI_4_INDEPENDENT_PROXY},
 *            {@link org.globus.gsi.GSIConstants.CertificateType#GSI_4_RESTRICTED_PROXY GSIConstants.CertificateType.GSI_4_RESTRICTED_PROXY}.
 *
 * @param extSet
 *            a set of X.509 extensions to be included in the new proxy certificate. Can be null. If
 *            delegation mode is {@link org.globus.gsi.GSIConstants.CertificateType#GSI_3_RESTRICTED_PROXY
 *            GSIConstants.CertificateType.GSI_3_RESTRICTED_PROXY} or {@link org.globus.gsi.GSIConstants.CertificateType#GSI_4_RESTRICTED_PROXY
 *            GSIConstants.CertificateType.GSI_4_RESTRICTED_PROXY} then
 *            {@link org.globus.gsi.proxy.ext.ProxyCertInfoExtension ProxyCertInfoExtension} must be
 *            present in the extension set.
 *
 * @param cnValue
 *            the value of the CN component of the subject of the new certificate. If null, the defaults
 *            will be used depending on the proxy certificate type created.
 * @return <code>X509Certificate</code> the new proxy certificate.
 * @exception GeneralSecurityException
 *                if a security error occurs.
 */
public X509Certificate createProxyCertificate(X509Certificate issuerCert_, PrivateKey issuerKey,
        PublicKey publicKey, int lifetime, GSIConstants.CertificateType certType, X509ExtensionSet extSet,
        String cnValue) throws GeneralSecurityException {

    X509Certificate issuerCert = issuerCert_;
    if (!(issuerCert_ instanceof X509CertificateObject)) {
        issuerCert = CertificateLoadUtil.loadCertificate(new ByteArrayInputStream(issuerCert.getEncoded()));
    }

    X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

    org.globus.gsi.X509Extension x509Ext = null;
    BigInteger serialNum = null;
    String delegDN = null;

    if (ProxyCertificateUtil.isGsi3Proxy(certType) || ProxyCertificateUtil.isGsi4Proxy(certType)) {
        Random rand = new Random();
        delegDN = String.valueOf(Math.abs(rand.nextInt()));
        serialNum = new BigInteger(20, rand);

        if (extSet != null) {
            x509Ext = extSet.get(ProxyCertInfo.OID.getId());
            if (x509Ext == null) {
                x509Ext = extSet.get(ProxyCertInfo.OLD_OID.getId());
            }
        }

        if (x509Ext == null) {
            // create ProxyCertInfo extension
            ProxyPolicy policy = null;
            if (ProxyCertificateUtil.isLimitedProxy(certType)) {
                policy = new ProxyPolicy(ProxyPolicy.LIMITED);
            } else if (ProxyCertificateUtil.isIndependentProxy(certType)) {
                policy = new ProxyPolicy(ProxyPolicy.INDEPENDENT);
            } else if (ProxyCertificateUtil.isImpersonationProxy(certType)) {
                // since limited has already been checked, this should work.
                policy = new ProxyPolicy(ProxyPolicy.IMPERSONATION);
            } else if ((certType == GSIConstants.CertificateType.GSI_3_RESTRICTED_PROXY)
                    || (certType == GSIConstants.CertificateType.GSI_4_RESTRICTED_PROXY)) {
                String err = i18n.getMessage("restrictProxy");
                throw new IllegalArgumentException(err);
            } else {
                String err = i18n.getMessage("invalidProxyType");
                throw new IllegalArgumentException(err);
            }

            ProxyCertInfo proxyCertInfo = new ProxyCertInfo(policy);
            x509Ext = new ProxyCertInfoExtension(proxyCertInfo);
            if (ProxyCertificateUtil.isGsi4Proxy(certType)) {
                // RFC compliant OID
                x509Ext = new ProxyCertInfoExtension(proxyCertInfo);
            } else {
                // old OID
                x509Ext = new GlobusProxyCertInfoExtension(proxyCertInfo);
            }
        }

        try {
            // add ProxyCertInfo extension to the new cert
            certGen.addExtension(x509Ext.getOid(), x509Ext.isCritical(), x509Ext.getValue());

            // handle KeyUsage in issuer cert
            TBSCertificateStructure crt = BouncyCastleUtil.getTBSCertificateStructure(issuerCert);

            X509Extensions extensions = crt.getExtensions();
            if (extensions != null) {
                X509Extension ext;

                // handle key usage ext
                ext = extensions.getExtension(X509Extension.keyUsage);
                if (ext != null) {

                    // TBD: handle this better
                    if (extSet != null && (extSet.get(X509Extension.keyUsage.getId()) != null)) {
                        String err = i18n.getMessage("keyUsageExt");
                        throw new GeneralSecurityException(err);
                    }

                    DERBitString bits = (DERBitString) BouncyCastleUtil.getExtensionObject(ext);

                    byte[] bytes = bits.getBytes();

                    // make sure they are disabled
                    if ((bytes[0] & KeyUsage.nonRepudiation) != 0) {
                        bytes[0] ^= KeyUsage.nonRepudiation;
                    }

                    if ((bytes[0] & KeyUsage.keyCertSign) != 0) {
                        bytes[0] ^= KeyUsage.keyCertSign;
                    }

                    bits = new DERBitString(bytes, bits.getPadBits());

                    certGen.addExtension(X509Extension.keyUsage, ext.isCritical(), bits);
                }
            }

        } catch (IOException e) {
            // but this should not happen
            throw new GeneralSecurityException(e.getMessage());
        }

    } else if (certType == GSIConstants.CertificateType.GSI_2_LIMITED_PROXY) {
        delegDN = "limited proxy";
        serialNum = issuerCert.getSerialNumber();
    } else if (certType == GSIConstants.CertificateType.GSI_2_PROXY) {
        delegDN = "proxy";
        serialNum = issuerCert.getSerialNumber();
    } else {
        String err = i18n.getMessage("unsupportedProxy", certType);
        throw new IllegalArgumentException(err);
    }

    // add specified extensions
    if (extSet != null) {
        Iterator iter = extSet.oidSet().iterator();
        while (iter.hasNext()) {
            String oid = (String) iter.next();
            // skip ProxyCertInfo extension
            if (oid.equals(ProxyCertInfo.OID.getId()) || oid.equals(ProxyCertInfo.OLD_OID.getId())) {
                continue;
            }
            x509Ext = (org.globus.gsi.X509Extension) extSet.get(oid);
            certGen.addExtension(x509Ext.getOid(), x509Ext.isCritical(), x509Ext.getValue());
        }
    }

    X509Name issuerDN;
    if (issuerCert.getSubjectDN() instanceof X509Name) {
        issuerDN = (X509Name) issuerCert.getSubjectDN();
    } else {
        issuerDN = new X509Name(true, issuerCert.getSubjectX500Principal().getName());
    }
    X509NameHelper issuer = new X509NameHelper(issuerDN);
    X509NameHelper subject = new X509NameHelper(issuerDN);
    subject.add(BCStyle.CN, (cnValue == null) ? delegDN : cnValue);

    certGen.setSubjectDN(subject.getAsName());
    certGen.setIssuerDN(issuer.getAsName());

    certGen.setSerialNumber(serialNum);
    certGen.setPublicKey(publicKey);
    certGen.setSignatureAlgorithm(issuerCert.getSigAlgName());

    GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    /* Allow for a five minute clock skew here. */
    date.add(Calendar.MINUTE, -5);
    certGen.setNotBefore(date.getTime());

    /* If hours = 0, then cert lifetime is set to user cert */
    if (lifetime <= 0) {
        certGen.setNotAfter(issuerCert.getNotAfter());
    } else {
        date.add(Calendar.MINUTE, 5);
        date.add(Calendar.SECOND, lifetime);
        certGen.setNotAfter(date.getTime());
    }

    return certGen.generateX509Certificate(issuerKey);
}

From source file:org.globus.gsi.bc.BouncyCastleUtil.java

License:Apache License

/**
 * Returns certificate type of the given TBS certificate. <BR>
 * The certificate type is {@link GSIConstants#CA GSIConstants.CA}
 * <B>only</B> if the certificate contains a
 * BasicConstraints extension and it is marked as CA.<BR>
 * A certificate is a GSI-2 proxy when the subject DN of the certificate
 * ends with <I>"CN=proxy"</I> (certificate type {@link
 * GSIConstants#GSI_2_PROXY GSIConstants.GSI_2_PROXY}) or
 * <I>"CN=limited proxy"</I> (certificate type {@link
 * GSIConstants#GSI_2_LIMITED_PROXY GSIConstants.LIMITED_PROXY}) component
 * and the issuer DN of the certificate matches the subject DN without
 * the last proxy <I>CN</I> component.<BR>
 * A certificate is a GSI-3 proxy when the subject DN of the certificate
 * ends with a <I>CN</I> component, the issuer DN of the certificate
 * matches the subject DN without the last <I>CN</I> component and
 * the certificate contains {@link ProxyCertInfo ProxyCertInfo} critical
 * extension.//from w  w w  .  j  av a  2  s .c  om
 * The certificate type is {@link GSIConstants#GSI_3_IMPERSONATION_PROXY
 * GSIConstants.GSI_3_IMPERSONATION_PROXY} if the policy language of
 * the {@link ProxyCertInfo ProxyCertInfo} extension is set to
 * {@link ProxyPolicy#IMPERSONATION ProxyPolicy.IMPERSONATION} OID.
 * The certificate type is {@link GSIConstants#GSI_3_LIMITED_PROXY
 * GSIConstants.GSI_3_LIMITED_PROXY} if the policy language of
 * the {@link ProxyCertInfo ProxyCertInfo} extension is set to
 * {@link ProxyPolicy#LIMITED ProxyPolicy.LIMITED} OID.
 * The certificate type is {@link GSIConstants#GSI_3_INDEPENDENT_PROXY
 * GSIConstants.GSI_3_INDEPENDENT_PROXY} if the policy language of
 * the {@link ProxyCertInfo ProxyCertInfo} extension is set to
 * {@link ProxyPolicy#INDEPENDENT ProxyPolicy.INDEPENDENT} OID.
 * The certificate type is {@link GSIConstants#GSI_3_RESTRICTED_PROXY
 * GSIConstants.GSI_3_RESTRICTED_PROXY} if the policy language of
 * the {@link ProxyCertInfo ProxyCertInfo} extension is set to
 * any other OID then the above.<BR>
 * The certificate type is {@link GSIConstants#EEC GSIConstants.EEC}
 * if the certificate is not a CA certificate or a GSI-2 or GSI-3 proxy.
 *
 * @param crt the TBS certificate to get the type of.
 * @return the certificate type. The certificate type is determined
 *         by rules described above.
 * @exception IOException if something goes wrong.
 * @exception CertificateException for proxy certificates, if
 *            the issuer DN of the certificate does not match
 *            the subject DN of the certificate without the
 *            last <I>CN</I> component. Also, for GSI-3 proxies
 *            when the <code>ProxyCertInfo</code> extension is
 *            not marked as critical.
 */
private static GSIConstants.CertificateType getCertificateType(TBSCertificateStructure crt)
        throws CertificateException, IOException {
    X509Extensions extensions = crt.getExtensions();
    X509Extension ext = null;

    if (extensions != null) {
        ext = extensions.getExtension(X509Extension.basicConstraints);
        if (ext != null) {
            BasicConstraints basicExt = BasicConstraints.getInstance(ext);
            if (basicExt.isCA()) {
                return GSIConstants.CertificateType.CA;
            }
        }
    }

    GSIConstants.CertificateType type = GSIConstants.CertificateType.EEC;

    // does not handle multiple AVAs
    X500Name subject = crt.getSubject();

    ASN1Set entry = X509NameHelper.getLastNameEntry(subject);
    ASN1Sequence ava = (ASN1Sequence) entry.getObjectAt(0);
    if (BCStyle.CN.equals(ava.getObjectAt(0))) {
        String value = ((ASN1String) ava.getObjectAt(1)).getString();
        if (value.equalsIgnoreCase("proxy")) {
            type = GSIConstants.CertificateType.GSI_2_PROXY;
        } else if (value.equalsIgnoreCase("limited proxy")) {
            type = GSIConstants.CertificateType.GSI_2_LIMITED_PROXY;
        } else if (extensions != null) {
            boolean gsi4 = true;
            // GSI_4
            ext = extensions.getExtension(ProxyCertInfo.OID);
            if (ext == null) {
                // GSI_3
                ext = extensions.getExtension(ProxyCertInfo.OLD_OID);
                gsi4 = false;
            }
            if (ext != null) {
                if (ext.isCritical()) {
                    ProxyCertInfo proxyCertExt = getProxyCertInfo(ext);
                    ProxyPolicy proxyPolicy = proxyCertExt.getProxyPolicy();
                    ASN1ObjectIdentifier oid = proxyPolicy.getPolicyLanguage();
                    if (ProxyPolicy.IMPERSONATION.equals(oid)) {
                        if (gsi4) {
                            type = GSIConstants.CertificateType.GSI_4_IMPERSONATION_PROXY;
                        } else {
                            type = GSIConstants.CertificateType.GSI_3_IMPERSONATION_PROXY;
                        }
                    } else if (ProxyPolicy.INDEPENDENT.equals(oid)) {
                        if (gsi4) {
                            type = GSIConstants.CertificateType.GSI_4_INDEPENDENT_PROXY;
                        } else {
                            type = GSIConstants.CertificateType.GSI_3_INDEPENDENT_PROXY;
                        }
                    } else if (ProxyPolicy.LIMITED.equals(oid)) {
                        if (gsi4) {
                            type = GSIConstants.CertificateType.GSI_4_LIMITED_PROXY;
                        } else {
                            type = GSIConstants.CertificateType.GSI_3_LIMITED_PROXY;
                        }
                    } else {
                        if (gsi4) {
                            type = GSIConstants.CertificateType.GSI_4_RESTRICTED_PROXY;
                        } else {
                            type = GSIConstants.CertificateType.GSI_3_RESTRICTED_PROXY;
                        }
                    }

                } else {
                    String err = i18n.getMessage("proxyCertCritical");
                    throw new CertificateException(err);
                }
            }
        }

        if (ProxyCertificateUtil.isProxy(type)) {
            X509NameHelper iss = new X509NameHelper(crt.getIssuer());
            iss.add((ASN1Set) BouncyCastleUtil.duplicate(entry));
            X509Name issuer = iss.getAsName();
            if (!issuer.equals(X509Name.getInstance(subject))) {
                String err = i18n.getMessage("proxyDNErr");
                throw new CertificateException(err);
            }
        }
    }

    return type;
}

From source file:org.globus.gsi.bc.BouncyCastleUtil.java

License:Apache License

public static ProxyCertInfo getProxyCertInfo(TBSCertificateStructure crt) throws IOException {

    X509Extensions extensions = crt.getExtensions();
    if (extensions == null) {
        return null;
    }/*from  w  w w. ja va  2 s.  co  m*/
    X509Extension ext = extensions.getExtension(ProxyCertInfo.OID);
    if (ext == null) {
        ext = extensions.getExtension(ProxyCertInfo.OLD_OID);
    }
    return (ext != null) ? BouncyCastleUtil.getProxyCertInfo(ext) : null;
}

From source file:org.globus.gsi.trustmanager.X509ProxyCertPathValidator.java

License:Apache License

@SuppressWarnings("unused")
protected void checkProxyConstraints(TBSCertificateStructure proxy, TBSCertificateStructure issuer,
        X509Certificate checkedProxy) throws CertPathValidatorException, IOException {

    X509Extensions extensions;
    ASN1ObjectIdentifier oid;/*from  w  ww .  ja v a2  s . c o m*/
    X509Extension proxyExtension;

    X509Extension proxyKeyUsage = null;

    extensions = proxy.getExtensions();
    if (extensions != null) {
        Enumeration e = extensions.oids();
        while (e.hasMoreElements()) {
            oid = (ASN1ObjectIdentifier) e.nextElement();
            proxyExtension = extensions.getExtension(oid);
            if (oid.equals(X509Extension.subjectAlternativeName)
                    || oid.equals(X509Extension.issuerAlternativeName)) {
                // No Alt name extensions - 3.2 & 3.5
                throw new CertPathValidatorException("Proxy violation: no Subject or Issuer Alternative Name");
            } else if (oid.equals(X509Extension.basicConstraints)) {
                // Basic Constraint must not be true - 3.8
                BasicConstraints basicExt = CertificateUtil.getBasicConstraints(proxyExtension);
                if (basicExt.isCA()) {
                    throw new CertPathValidatorException("Proxy violation: Basic Constraint CA is set to true");
                }
            } else if (oid.equals(X509Extension.keyUsage)) {
                proxyKeyUsage = proxyExtension;

                checkKeyUsage(issuer, proxyExtension);
            }
        }
    }

    extensions = issuer.getExtensions();

    if (extensions != null) {
        Enumeration e = extensions.oids();
        while (e.hasMoreElements()) {
            oid = (ASN1ObjectIdentifier) e.nextElement();
            proxyExtension = extensions.getExtension(oid);
            checkExtension(oid, proxyExtension, proxyKeyUsage);
        }
    }

}

From source file:org.globus.gsi.util.CertificateUtil.java

License:Apache License

/**
 * Return CA Path constraint/*from w ww .  j a v a2 s  .  c o  m*/
 *
 * @param crt
 * @return the CA path constraint
 * @throws IOException
 */
public static int getCAPathConstraint(TBSCertificateStructure crt) throws IOException {

    X509Extensions extensions = crt.getExtensions();
    if (extensions == null) {
        return -1;
    }
    X509Extension proxyExtension = extensions.getExtension(X509Extension.basicConstraints);
    if (proxyExtension != null) {
        BasicConstraints basicExt = getBasicConstraints(proxyExtension);
        if (basicExt.isCA()) {
            BigInteger pathLen = basicExt.getPathLenConstraint();
            return (pathLen == null) ? Integer.MAX_VALUE : pathLen.intValue();
        } else {
            return -1;
        }
    }
    return -1;
}