Saturday, August 23, 2014

Signing Certificate Signing Request (CSR) using bouncycastle 1.49

Digital Certificates are used to used to prove the ownership of public keys in the Public Key Infrastructure. It usually consist of the details of the Subject (The entity to whom the certificate is issued), the details of the Issuer by whom the certificate is signed (Usually a Certificate Authority (CA), can be the subject itself in case of self signed certificates), the public key, a serial number and optionally some other properties.

To get the public key signed, the subject first create a Certificate Signing Request (CSR), Which contains the public key and the details of the subject such as Distinguished Name (DN), Organization (O), Organization Unit (OU), State (ST), Country(C). The CA then verify these details and sign (or reject) the request.

If you are using Java to sign a certificate, you can use Bouncy Castle to sign the CSRs programmatically. Following code will explain how it can be done with bouncycastle 1.49.
In order to use bouncycastle, you need to add the bcprov and bcpkix jars to the classpath which can be downloaded from [1] and add the bouncycastle provider as,

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());


We'll begin by creating a PKCS10CertificationRequest object from the CSR

encodedCsr = "....." //The PEM encoded CSR's text content
PEMParser pemParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(encodedCsr.getBytes())));
PKCS10CertificationRequest request = (PKCS10CertificationRequest) pemParser.readObject();

Then sign the above created PKCS10CertificationRequest as follows,

try {
            int validity = 365; //No of days the certificate should be valid
            String serialNo = ...; // a unique number
            privateKey = ...; // The CA's private key
            caCert = ...; //The CA's certificate as a X509Certificate
            Date issuedDate = new Date();
            Date expiryDate = new Date(System.currentTimeMillis() + validity * MILLIS_PER_DAY); //MILLIS_PER_DAY=86400000l
            JcaPKCS10CertificationRequest jcaRequest = new JcaPKCS10CertificationRequest(request);
            X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(caCert,
                    new BigInteger(serialNo), issuedDate, expiryDate, jcaRequest.getSubject(), jcaRequest.getPublicKey());
            JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
            certificateBuilder.addExtension(Extension.authorityKeyIdentifier, false,
                    extUtils.createAuthorityKeyIdentifier(caCert))
                    .addExtension(Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(jcaRequest
                            .getPublicKey()))
                    .addExtension(Extension.basicConstraints, true, new BasicConstraints(0))
                    .addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage
                            .keyEncipherment))
                    .addExtension(Extension.extendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeId.id_kp_serverAuth));
            ContentSigner signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privateKey);

            //Add the CRL endpoint
            DistributionPointName crlEp = new DistributionPointName(new GeneralNames(new GeneralName(GeneralName
                    .uniformResourceIdentifier, CA_CRL_ENDPOINT_URL)));
            DistributionPoint disPoint = new DistributionPoint(crlEp, null, null);
            certificateBuilder.addExtension(Extension.cRLDistributionPoints, false,
                    new CRLDistPoint(new DistributionPoint[]{disPoint}));

            //Add the OCSP endpoint
            AccessDescription ocsp = new AccessDescription(AccessDescription.id_ad_ocsp,
                    new GeneralName(GeneralName.uniformResourceIdentifier, CA_OCSP_ENDPOINT_URL)
            );
            ASN1EncodableVector authInfoAccessASN = new ASN1EncodableVector();
            authInfoAccessASN.add(ocsp);
            certificateBuilder.addExtension(Extension.authorityInfoAccess, false, new DERSequence(authInfoAccessASN));
            X509Certificate signedCert = new JcaX509CertificateConverter().setProvider("BC").getCertificate
                    (certificateBuilder.build(signer));
        } catch (Exception e) {
            throw new CaException("Error in signing the certificate", e);
        }


[1] https://www.bouncycastle.org/latest_releases.html

Saturday, June 7, 2014

Application Authentication using IWA with WSO2 IS 5.0

WSO2 Identity Server is an open source Identity and Entitlement management server. It supports a wide array of authentication and authorization mechanisms. One of its' new features is the application authentication framework, which is capable of translating between heterogeneous authentication protocols and transforming and mediating any identity assertion.

Integrated Windows Authentication (IWA) is an authentication mechanism introduced by Microsoft to authenticate users in Microsoft Windows NT based operating systems. IWA authentication provides an easier way for users to log in to web applications that use Windows Active Directory as an user store. It is a popular choice of authentication among Windows server users and administrators, since it eliminate the need of remembering extra credentials to the users and, reduces the authentication overhead for the server administrators.

In this post I will explain how to configure WSO2 Identity Server to authenticate users to web applications using Integrated Windows Authentication. I will use the “Travelocity.com” sample application that is available in WSO2 Identity Server samples, for the demonstration.