Search in sources :

Example 61 with Request

use of org.bouncycastle.asn1.ocsp.Request in project ddf by codice.

the class LoginFilter method handleAuthenticationToken.

private Subject handleAuthenticationToken(HttpServletRequest httpRequest, SAMLAuthenticationToken token) throws ServletException {
    Subject subject;
    try {
        LOGGER.debug("Validating received SAML assertion.");
        boolean wasReference = false;
        boolean firstLogin = true;
        if (token.isReference()) {
            wasReference = true;
            LOGGER.trace("Converting SAML reference to assertion");
            Object sessionToken = httpRequest.getSession(false).getAttribute(SecurityConstants.SAML_ASSERTION);
            if (LOGGER.isTraceEnabled()) {
                LOGGER.trace("Http Session assertion - class: {}  loader: {}", sessionToken.getClass().getName(), sessionToken.getClass().getClassLoader());
                LOGGER.trace("SecurityToken class: {}  loader: {}", SecurityToken.class.getName(), SecurityToken.class.getClassLoader());
            }
            SecurityToken savedToken = null;
            try {
                savedToken = ((SecurityTokenHolder) sessionToken).getSecurityToken(token.getRealm());
            } catch (ClassCastException e) {
                httpRequest.getSession(false).invalidate();
            }
            if (savedToken != null) {
                firstLogin = false;
                token.replaceReferenece(savedToken);
            }
            if (token.isReference()) {
                String msg = "Missing or invalid SAML assertion for provided reference.";
                LOGGER.debug(msg);
                throw new InvalidSAMLReceivedException(msg);
            }
        }
        SAMLAuthenticationToken newToken = renewSecurityToken(httpRequest.getSession(false), token);
        SecurityToken securityToken;
        if (newToken != null) {
            firstLogin = false;
            securityToken = (SecurityToken) newToken.getCredentials();
        } else {
            securityToken = (SecurityToken) token.getCredentials();
        }
        if (!wasReference) {
            // wrap the token
            SamlAssertionWrapper assertion = new SamlAssertionWrapper(securityToken.getToken());
            // get the crypto junk
            Crypto crypto = getSignatureCrypto();
            Response samlResponse = createSamlResponse(httpRequest.getRequestURI(), assertion.getIssuerString(), createStatus(SAMLProtocolResponseValidator.SAML2_STATUSCODE_SUCCESS, null));
            BUILDER.get().reset();
            Document doc = BUILDER.get().newDocument();
            Element policyElement = OpenSAMLUtil.toDom(samlResponse, doc);
            doc.appendChild(policyElement);
            Credential credential = new Credential();
            credential.setSamlAssertion(assertion);
            RequestData requestData = new RequestData();
            requestData.setSigVerCrypto(crypto);
            WSSConfig wssConfig = WSSConfig.getNewInstance();
            requestData.setWssConfig(wssConfig);
            X509Certificate[] x509Certs = (X509Certificate[]) httpRequest.getAttribute("javax.servlet.request.X509Certificate");
            requestData.setTlsCerts(x509Certs);
            validateHolderOfKeyConfirmation(assertion, x509Certs);
            if (assertion.isSigned()) {
                // Verify the signature
                WSSSAMLKeyInfoProcessor wsssamlKeyInfoProcessor = new WSSSAMLKeyInfoProcessor(requestData, new WSDocInfo(samlResponse.getDOM().getOwnerDocument()));
                assertion.verifySignature(wsssamlKeyInfoProcessor, crypto);
                assertion.parseSubject(new WSSSAMLKeyInfoProcessor(requestData, new WSDocInfo(samlResponse.getDOM().getOwnerDocument())), requestData.getSigVerCrypto(), requestData.getCallbackHandler());
            }
            // Validate the Assertion & verify trust in the signature
            assertionValidator.validate(credential, requestData);
        }
        // if it is all good, then we'll create our subject
        subject = securityManager.getSubject(securityToken);
        if (firstLogin) {
            boolean hasSecurityAuditRole = Arrays.stream(System.getProperty("security.audit.roles").split(",")).filter(subject::hasRole).findFirst().isPresent();
            if (hasSecurityAuditRole) {
                SecurityLogger.audit("Subject has logged in with admin privileges", subject);
            }
        }
        if (!wasReference && firstLogin) {
            addSamlToSession(httpRequest, token.getRealm(), securityToken);
        }
    } catch (SecurityServiceException e) {
        LOGGER.debug("Unable to get subject from SAML request.", e);
        throw new ServletException(e);
    } catch (WSSecurityException e) {
        LOGGER.debug("Unable to read/validate security token from request.", e);
        throw new ServletException(e);
    }
    return subject;
}
Also used : WSDocInfo(org.apache.wss4j.dom.WSDocInfo) Credential(org.apache.wss4j.dom.validate.Credential) SecurityServiceException(ddf.security.service.SecurityServiceException) Element(org.w3c.dom.Element) SamlAssertionWrapper(org.apache.wss4j.common.saml.SamlAssertionWrapper) WSSecurityException(org.apache.wss4j.common.ext.WSSecurityException) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) InvalidSAMLReceivedException(org.codice.ddf.security.handler.api.InvalidSAMLReceivedException) Document(org.w3c.dom.Document) SAMLAuthenticationToken(org.codice.ddf.security.handler.api.SAMLAuthenticationToken) Subject(ddf.security.Subject) X509Certificate(java.security.cert.X509Certificate) SecurityToken(org.apache.cxf.ws.security.tokenstore.SecurityToken) Response(org.opensaml.saml.saml2.core.Response) ServletResponse(javax.servlet.ServletResponse) ServletException(javax.servlet.ServletException) Crypto(org.apache.wss4j.common.crypto.Crypto) WSSConfig(org.apache.wss4j.dom.engine.WSSConfig) RequestData(org.apache.wss4j.dom.handler.RequestData) WSSSAMLKeyInfoProcessor(org.apache.wss4j.dom.saml.WSSSAMLKeyInfoProcessor)

Example 62 with Request

use of org.bouncycastle.asn1.ocsp.Request in project athenz by yahoo.

the class ZTSClient method generateRoleCertificateRequest.

/**
 * Generate a Role Certificate request that could be sent to ZTS
 * to obtain a X509 Certificate for the requested role.
 * @param principalDomain name of the principal's domain
 * @param principalService name of the principal's service
 * @param roleDomainName name of the domain where role is defined
 * @param roleName name of the role to get a certificate request for
 * @param privateKey private key for the service identity for the caller
 * @param csrDn string identifying the dn for the csr without the cn component
 * @param csrDomain string identifying the dns domain for generating SAN fields
 * @param expiryTime number of seconds to request certificate to be valid for
 * @return RoleCertificateRequest object
 */
public static RoleCertificateRequest generateRoleCertificateRequest(final String principalDomain, final String principalService, final String roleDomainName, final String roleName, PrivateKey privateKey, final String csrDn, final String csrDomain, int expiryTime) {
    if (principalDomain == null || principalService == null) {
        throw new IllegalArgumentException("Principal's Domain and Service must be specified");
    }
    if (roleDomainName == null || roleName == null) {
        throw new IllegalArgumentException("Role DomainName and Name must be specified");
    }
    if (csrDomain == null) {
        throw new IllegalArgumentException("X509 CSR Domain must be specified");
    }
    // Athenz uses lower case for all elements, so let's
    // generate our dn which will be our role resource value
    final String domain = principalDomain.toLowerCase();
    final String service = principalService.toLowerCase();
    String dn = "cn=" + roleDomainName.toLowerCase() + ":role." + roleName.toLowerCase();
    if (csrDn != null) {
        dn = dn.concat(",").concat(csrDn);
    }
    // now let's generate our dsnName and email fields which will based on
    // our principal's details
    StringBuilder hostBuilder = new StringBuilder(128);
    hostBuilder.append(service);
    hostBuilder.append('.');
    hostBuilder.append(domain.replace('.', '-'));
    hostBuilder.append('.');
    hostBuilder.append(csrDomain);
    String hostName = hostBuilder.toString();
    String email = domain + "." + service + "@" + csrDomain;
    GeneralName[] sanArray = new GeneralName[2];
    sanArray[0] = new GeneralName(GeneralName.dNSName, new DERIA5String(hostName));
    sanArray[1] = new GeneralName(GeneralName.rfc822Name, new DERIA5String(email));
    String csr = null;
    try {
        csr = Crypto.generateX509CSR(privateKey, dn, sanArray);
    } catch (OperatorCreationException | IOException ex) {
        throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
    }
    RoleCertificateRequest req = new RoleCertificateRequest().setCsr(csr).setExpiryTime(Long.valueOf(expiryTime));
    return req;
}
Also used : DERIA5String(org.bouncycastle.asn1.DERIA5String) DERIA5String(org.bouncycastle.asn1.DERIA5String) GeneralName(org.bouncycastle.asn1.x509.GeneralName) IOException(java.io.IOException) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException)

Example 63 with Request

use of org.bouncycastle.asn1.ocsp.Request in project athenz by yahoo.

the class ZTSClient method cacheSvcProvRoleToken.

/**
 * stuff pre-loaded service token in cache. in this model an external
 * service (proxy user) has retrieved the role tokens and added to the
 * client cache so it can run without the need to contact zts server.
 * in this model we're going to look at the principal field only and
 * ignore the proxy field since the client doesn't need to know anything
 * about that detail.
 *
 * start prefetch task to reload to prevent expiry
 * return the cache key used
 */
static String cacheSvcProvRoleToken(ZTSClientService.RoleTokenDescriptor desc) {
    if (cacheDisabled) {
        return null;
    }
    com.yahoo.athenz.auth.token.RoleToken rt = new com.yahoo.athenz.auth.token.RoleToken(desc.getSignedToken());
    String domainName = rt.getDomain();
    String principalName = rt.getPrincipal();
    boolean completeRoleSet = rt.getDomainCompleteRoleSet();
    // if the role token was for a complete set then we're not going
    // to use the rolename field (it indicates that the original request
    // was completed without the rolename field being specified)
    final String roleName = (completeRoleSet) ? null : multipleRoleKey(rt.getRoles());
    // parse principalName for the tenant domain and service name
    // we must have valid components otherwise we'll just
    // ignore the token - you can't have a principal without
    // valid domain and service names
    // ex: cities.burbank.mysvc
    int index = principalName.lastIndexOf('.');
    if (index == -1) {
        LOG.error("cacheSvcProvRoleToken: Invalid principal in token: " + rt.getSignedToken());
        return null;
    }
    final String tenantDomain = principalName.substring(0, index);
    final String tenantService = principalName.substring(index + 1);
    Long expiryTime = rt.getExpiryTime();
    RoleToken roleToken = new RoleToken().setToken(desc.getSignedToken()).setExpiryTime(expiryTime);
    String key = getRoleTokenCacheKey(tenantDomain, tenantService, domainName, roleName, null);
    if (LOG.isInfoEnabled()) {
        LOG.info("cacheSvcProvRoleToken: cache-add key: " + key + " expiry: " + expiryTime);
    }
    ROLE_TOKEN_CACHE.put(key, roleToken);
    // setup prefetch task
    Long expiryTimeUTC = roleToken.getExpiryTime();
    prefetchSvcProvTokens(tenantDomain, tenantService, domainName, roleName, null, null, expiryTimeUTC, null);
    return key;
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) DERIA5String(org.bouncycastle.asn1.DERIA5String)

Example 64 with Request

use of org.bouncycastle.asn1.ocsp.Request in project athenz by yahoo.

the class ZTSClient method generateInstanceRefreshRequest.

/**
 * Generate a Instance Refresh request that could be sent to ZTS to
 * request a TLS certificate for a service.
 * @param principalDomain name of the principal's domain
 * @param principalService name of the principal's service
 * @param privateKey private key for the service identity for the caller
 * @param csrDn string identifying the dn for the csr without the cn component
 * @param csrDomain string identifying the dns domain for generating SAN fields
 * @param expiryTime number of seconds to request certificate to be valid for
 * @return InstanceRefreshRequest object
 */
public static InstanceRefreshRequest generateInstanceRefreshRequest(final String principalDomain, final String principalService, PrivateKey privateKey, final String csrDn, final String csrDomain, int expiryTime) {
    if (principalDomain == null || principalService == null) {
        throw new IllegalArgumentException("Principal's Domain and Service must be specified");
    }
    if (csrDomain == null) {
        throw new IllegalArgumentException("X509 CSR Domain must be specified");
    }
    // Athenz uses lower case for all elements, so let's
    // generate our dn which will be based on our service name
    final String domain = principalDomain.toLowerCase();
    final String service = principalService.toLowerCase();
    final String cn = domain + "." + service;
    String dn = "cn=" + cn;
    if (csrDn != null) {
        dn = dn.concat(",").concat(csrDn);
    }
    // now let's generate our dsnName field based on our principal's details
    StringBuilder hostBuilder = new StringBuilder(128);
    hostBuilder.append(service);
    hostBuilder.append('.');
    hostBuilder.append(domain.replace('.', '-'));
    hostBuilder.append('.');
    hostBuilder.append(csrDomain);
    String hostName = hostBuilder.toString();
    GeneralName[] sanArray = new GeneralName[1];
    sanArray[0] = new GeneralName(GeneralName.dNSName, new DERIA5String(hostName));
    String csr = null;
    try {
        csr = Crypto.generateX509CSR(privateKey, dn, sanArray);
    } catch (OperatorCreationException | IOException ex) {
        throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
    }
    InstanceRefreshRequest req = new InstanceRefreshRequest().setCsr(csr).setExpiryTime(Integer.valueOf(expiryTime));
    return req;
}
Also used : DERIA5String(org.bouncycastle.asn1.DERIA5String) DERIA5String(org.bouncycastle.asn1.DERIA5String) GeneralName(org.bouncycastle.asn1.x509.GeneralName) IOException(java.io.IOException) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException)

Example 65 with Request

use of org.bouncycastle.asn1.ocsp.Request in project nifi by apache.

the class OcspCertificateValidator method getOcspStatus.

/**
 * Gets the OCSP status for the specified subject and issuer certificates.
 *
 * @param ocspStatusKey status key
 * @return ocsp status
 */
private OcspStatus getOcspStatus(final OcspRequest ocspStatusKey) {
    final X509Certificate subjectCertificate = ocspStatusKey.getSubjectCertificate();
    final X509Certificate issuerCertificate = ocspStatusKey.getIssuerCertificate();
    // initialize the default status
    final OcspStatus ocspStatus = new OcspStatus();
    ocspStatus.setVerificationStatus(VerificationStatus.Unknown);
    ocspStatus.setValidationStatus(ValidationStatus.Unknown);
    try {
        // prepare the request
        final BigInteger subjectSerialNumber = subjectCertificate.getSerialNumber();
        final DigestCalculatorProvider calculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder().setProvider("BC").build();
        final CertificateID certificateId = new CertificateID(calculatorProviderBuilder.get(CertificateID.HASH_SHA1), new X509CertificateHolder(issuerCertificate.getEncoded()), subjectSerialNumber);
        // generate the request
        final OCSPReqBuilder requestGenerator = new OCSPReqBuilder();
        requestGenerator.addRequest(certificateId);
        // Create a nonce to avoid replay attack
        BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
        Extension ext = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, true, new DEROctetString(nonce.toByteArray()));
        requestGenerator.setRequestExtensions(new Extensions(new Extension[] { ext }));
        final OCSPReq ocspRequest = requestGenerator.build();
        // perform the request
        final Response response = getClientResponse(ocspRequest);
        // ensure the request was completed successfully
        if (Response.Status.OK.getStatusCode() != response.getStatusInfo().getStatusCode()) {
            logger.warn(String.format("OCSP request was unsuccessful (%s).", response.getStatus()));
            return ocspStatus;
        }
        // interpret the response
        OCSPResp ocspResponse = new OCSPResp(response.readEntity(InputStream.class));
        // verify the response status
        switch(ocspResponse.getStatus()) {
            case OCSPRespBuilder.SUCCESSFUL:
                ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Successful);
                break;
            case OCSPRespBuilder.INTERNAL_ERROR:
                ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.InternalError);
                break;
            case OCSPRespBuilder.MALFORMED_REQUEST:
                ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.MalformedRequest);
                break;
            case OCSPRespBuilder.SIG_REQUIRED:
                ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.SignatureRequired);
                break;
            case OCSPRespBuilder.TRY_LATER:
                ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.TryLater);
                break;
            case OCSPRespBuilder.UNAUTHORIZED:
                ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Unauthorized);
                break;
            default:
                ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Unknown);
                break;
        }
        // only proceed if the response was successful
        if (ocspResponse.getStatus() != OCSPRespBuilder.SUCCESSFUL) {
            logger.warn(String.format("OCSP request was unsuccessful (%s).", ocspStatus.getResponseStatus().toString()));
            return ocspStatus;
        }
        // ensure the appropriate response object
        final Object ocspResponseObject = ocspResponse.getResponseObject();
        if (ocspResponseObject == null || !(ocspResponseObject instanceof BasicOCSPResp)) {
            logger.warn(String.format("Unexpected OCSP response object: %s", ocspResponseObject));
            return ocspStatus;
        }
        // get the response object
        final BasicOCSPResp basicOcspResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
        // attempt to locate the responder certificate
        final X509CertificateHolder[] responderCertificates = basicOcspResponse.getCerts();
        if (responderCertificates.length != 1) {
            logger.warn(String.format("Unexpected number of OCSP responder certificates: %s", responderCertificates.length));
            return ocspStatus;
        }
        // get the responder certificate
        final X509Certificate trustedResponderCertificate = getTrustedResponderCertificate(responderCertificates[0], issuerCertificate);
        if (trustedResponderCertificate != null) {
            // verify the response
            if (basicOcspResponse.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(trustedResponderCertificate.getPublicKey()))) {
                ocspStatus.setVerificationStatus(VerificationStatus.Verified);
            } else {
                ocspStatus.setVerificationStatus(VerificationStatus.Unverified);
            }
        } else {
            ocspStatus.setVerificationStatus(VerificationStatus.Unverified);
        }
        // validate the response
        final SingleResp[] responses = basicOcspResponse.getResponses();
        for (SingleResp singleResponse : responses) {
            final CertificateID responseCertificateId = singleResponse.getCertID();
            final BigInteger responseSerialNumber = responseCertificateId.getSerialNumber();
            if (responseSerialNumber.equals(subjectSerialNumber)) {
                Object certStatus = singleResponse.getCertStatus();
                // interpret the certificate status
                if (CertificateStatus.GOOD == certStatus) {
                    ocspStatus.setValidationStatus(ValidationStatus.Good);
                } else if (certStatus instanceof RevokedStatus) {
                    ocspStatus.setValidationStatus(ValidationStatus.Revoked);
                } else {
                    ocspStatus.setValidationStatus(ValidationStatus.Unknown);
                }
            }
        }
    } catch (final OCSPException | IOException | ProcessingException | OperatorCreationException e) {
        logger.error(e.getMessage(), e);
    } catch (CertificateException e) {
        e.printStackTrace();
    }
    return ocspStatus;
}
Also used : CertificateException(java.security.cert.CertificateException) Extensions(org.bouncycastle.asn1.x509.Extensions) DEROctetString(org.bouncycastle.asn1.DEROctetString) OCSPResp(org.bouncycastle.cert.ocsp.OCSPResp) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) OCSPException(org.bouncycastle.cert.ocsp.OCSPException) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) OCSPReqBuilder(org.bouncycastle.cert.ocsp.OCSPReqBuilder) SingleResp(org.bouncycastle.cert.ocsp.SingleResp) ProcessingException(javax.ws.rs.ProcessingException) CertificateID(org.bouncycastle.cert.ocsp.CertificateID) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) Extension(org.bouncycastle.asn1.x509.Extension) Response(javax.ws.rs.core.Response) JcaContentVerifierProviderBuilder(org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder) RevokedStatus(org.bouncycastle.cert.ocsp.RevokedStatus) DigestCalculatorProvider(org.bouncycastle.operator.DigestCalculatorProvider) OCSPReq(org.bouncycastle.cert.ocsp.OCSPReq) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) BigInteger(java.math.BigInteger) JcaDigestCalculatorProviderBuilder(org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder)

Aggregations

IOException (java.io.IOException)47 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)30 Date (java.util.Date)27 DEROctetString (org.bouncycastle.asn1.DEROctetString)26 BigInteger (java.math.BigInteger)23 X509Certificate (java.security.cert.X509Certificate)22 PKIMessage (org.bouncycastle.asn1.cmp.PKIMessage)22 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)20 CertificateException (java.security.cert.CertificateException)18 ArrayList (java.util.ArrayList)17 DERUTF8String (org.bouncycastle.asn1.DERUTF8String)17 X500Name (org.bouncycastle.asn1.x500.X500Name)16 Extension (org.bouncycastle.asn1.x509.Extension)16 Extensions (org.bouncycastle.asn1.x509.Extensions)16 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)15 DERIA5String (org.bouncycastle.asn1.DERIA5String)15 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)14 PKIBody (org.bouncycastle.asn1.cmp.PKIBody)13 ASN1Sequence (org.bouncycastle.asn1.ASN1Sequence)12 GeneralName (org.bouncycastle.asn1.x509.GeneralName)11