com.vmware.identity.sts.auth.impl.UserCertAuthenticatorTest.java Source code

Java tutorial

Introduction

Here is the source code for com.vmware.identity.sts.auth.impl.UserCertAuthenticatorTest.java

Source

/*
 *  Copyright (c) 2012-2015 VMware, Inc.  All Rights Reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not
 *  use this file except in compliance with the License.  You may obtain a copy
 *  of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, without
 *  warranties or conditions of any kind, EITHER EXPRESS OR IMPLIED.  See the
 *  License for the specific language governing permissions and limitations
 *  under the License.
 */

package com.vmware.identity.sts.auth.impl;

import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.util.Date;

import junit.framework.Assert;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.DERUTF8String;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.easymock.EasyMock;
import org.junit.BeforeClass;
import org.junit.Test;
import org.oasis_open.docs.ws_sx.ws_trust._200512.RequestSecurityTokenType;
import org.oasis_open.docs.wss._2004._01.oasis_200401_wss_wssecurity_secext_1_0.BinarySecurityTokenType;
import org.oasis_open.docs.wss._2004._01.oasis_200401_wss_wssecurity_secext_1_0.ObjectFactory;
import org.oasis_open.docs.wss._2004._01.oasis_200401_wss_wssecurity_secext_1_0.SecurityHeaderType;
import org.oasis_open.docs.wss._2004._01.oasis_200401_wss_wssecurity_secext_1_0.SignatureAlgorithmType;
import org.oasis_open.docs.wss._2004._01.oasis_200401_wss_wssecurity_secext_1_0.UserCertificateTokenType;
import org.w3._2000._09.xmldsig_.SignatureValueType;

import com.vmware.identity.idm.PrincipalId;
import com.vmware.identity.sts.InvalidCredentialsException;
import com.vmware.identity.sts.Request;
import com.vmware.identity.sts.auth.Authenticator;
import com.vmware.identity.sts.auth.Result;

public class UserCertAuthenticatorTest {

    static final String name = "user";
    static final String upn = name + "@ACMEC";
    static final String signedInfo = "vmware";
    static RSAPrivateKey userPrivateKey;
    static X509Certificate x509Certificate;

    public static final String ENCODING_TYPE_BASE64 = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary";
    public static final String X509_CERTIFICATE_TYPE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";

    @BeforeClass
    public static void setUp() throws Exception {
        // create key pair and client private key, certificate
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(1024, new SecureRandom());
        KeyPair userKeyPair = keyGen.generateKeyPair();
        userPrivateKey = (RSAPrivateKey) userKeyPair.getPrivate();
        x509Certificate = generateCertificate(userKeyPair, "User");
    }

    @Test
    public void testNullUserCertificateToken() throws Exception {
        com.vmware.identity.sts.idm.Authenticator idmAuth = EasyMock
                .createMock(com.vmware.identity.sts.idm.Authenticator.class);
        final Authenticator authenticator = new UserCertAuthenticator(idmAuth);

        final SecurityHeaderType header = new SecurityHeaderType();
        ObjectFactory objectFactory = new ObjectFactory();
        header.getAny().add(objectFactory.createUserCertificateToken(null));

        final Result authResult = authenticator.authenticate(newReq(header));
        Assert.assertNull(authResult);
    }

    @Test(expected = InvalidCredentialsException.class)
    public void testNullSignatureAlgorithm() throws Exception {
        com.vmware.identity.sts.idm.Authenticator idmAuth = EasyMock
                .createMock(com.vmware.identity.sts.idm.Authenticator.class);
        final Authenticator authenticator = new UserCertAuthenticator(idmAuth);

        final SecurityHeaderType header = new SecurityHeaderType();
        final UserCertificateTokenType userCertiticateToken = new UserCertificateTokenType();
        userCertiticateToken.setSignatureAlgorithm(null);
        ObjectFactory objectFactory = new ObjectFactory();
        header.getAny().add(objectFactory.createUserCertificateToken(userCertiticateToken));

        final Result authResult = authenticator.authenticate(newReq(header));
        Assert.assertNull(authResult);
    }

    @Test(expected = InvalidCredentialsException.class)
    public void testNullSignatureValueData() throws Exception {
        com.vmware.identity.sts.idm.Authenticator idmAuth = EasyMock
                .createMock(com.vmware.identity.sts.idm.Authenticator.class);
        final Authenticator authenticator = new UserCertAuthenticator(idmAuth);

        final SecurityHeaderType header = new SecurityHeaderType();
        final UserCertificateTokenType userCertiticateToken = new UserCertificateTokenType();
        BinarySecurityTokenType binarySecurityToken = new BinarySecurityTokenType();
        binarySecurityToken.setValueType(X509_CERTIFICATE_TYPE);
        binarySecurityToken.setEncodingType(ENCODING_TYPE_BASE64);
        // base64 encode the x509 certificate
        binarySecurityToken.setValue(new String(Base64.encodeBase64(x509Certificate.getEncoded())));
        userCertiticateToken.setUserCertificate(binarySecurityToken);

        userCertiticateToken.setSignatureInfo(signedInfo);
        userCertiticateToken.setSignatureAlgorithm(SignatureAlgorithmType.SHA_256_WITH_RSA);

        SignatureValueType signatureValueType = new SignatureValueType();
        signatureValueType.setValue(null);
        userCertiticateToken.setSignatureValue(signatureValueType);

        ObjectFactory objectFactory = new ObjectFactory();
        header.getAny().add(objectFactory.createUserCertificateToken(userCertiticateToken));

        authenticator.authenticate(newReq(header));
    }

    @Test(expected = InvalidCredentialsException.class)
    public void testSignatureVerfificationFailure() throws Exception {
        com.vmware.identity.sts.idm.Authenticator idmAuth = EasyMock
                .createMock(com.vmware.identity.sts.idm.Authenticator.class);
        final Authenticator authenticator = new UserCertAuthenticator(idmAuth);

        final SecurityHeaderType header = new SecurityHeaderType();
        final UserCertificateTokenType userCertiticateToken = new UserCertificateTokenType();
        BinarySecurityTokenType binarySecurityToken = new BinarySecurityTokenType();
        binarySecurityToken.setValueType(X509_CERTIFICATE_TYPE);
        binarySecurityToken.setEncodingType(ENCODING_TYPE_BASE64);
        // base64 encode the x509 certificate
        binarySecurityToken.setValue(new String(Base64.encodeBase64(x509Certificate.getEncoded())));
        userCertiticateToken.setUserCertificate(binarySecurityToken);

        userCertiticateToken.setSignatureInfo(signedInfo);
        userCertiticateToken.setSignatureAlgorithm(SignatureAlgorithmType.SHA_256_WITH_RSA);

        SignatureValueType signatureValueType = new SignatureValueType();
        signatureValueType.setValue(new byte[] { 0 });
        userCertiticateToken.setSignatureValue(signatureValueType);

        ObjectFactory objectFactory = new ObjectFactory();
        header.getAny().add(objectFactory.createUserCertificateToken(userCertiticateToken));

        authenticator.authenticate(newReq(header));
    }

    @Test
    public void testOK() throws Exception {
        com.vmware.identity.sts.idm.Authenticator idmAuth = EasyMock
                .createMock(com.vmware.identity.sts.idm.Authenticator.class);

        final PrincipalId principalIdc13d = new PrincipalId(name, "acme.com");

        EasyMock.expect(idmAuth.authenticate(EasyMock.isA(X509Certificate[].class))).andReturn(principalIdc13d);
        EasyMock.replay(idmAuth);

        final Authenticator authenticator = new UserCertAuthenticator(idmAuth);

        final SecurityHeaderType header = new SecurityHeaderType();
        final UserCertificateTokenType userCertiticateToken = new UserCertificateTokenType();
        BinarySecurityTokenType binarySecurityToken = new BinarySecurityTokenType();
        binarySecurityToken.setValueType(X509_CERTIFICATE_TYPE);
        binarySecurityToken.setEncodingType(ENCODING_TYPE_BASE64);
        // base64 encode the x509 certificate
        binarySecurityToken.setValue(new String(Base64.encodeBase64(x509Certificate.getEncoded())));
        userCertiticateToken.setUserCertificate(binarySecurityToken);

        userCertiticateToken.setSignatureInfo(signedInfo);
        userCertiticateToken.setSignatureAlgorithm(SignatureAlgorithmType.SHA_256_WITH_RSA);

        SignatureValueType signatureValueType = new SignatureValueType();
        Signature dsa = Signature.getInstance("SHA256withRSA");
        dsa.initSign(userPrivateKey);
        dsa.update(signedInfo.getBytes());
        signatureValueType.setValue(dsa.sign());
        userCertiticateToken.setSignatureValue(signatureValueType);

        ObjectFactory objectFactory = new ObjectFactory();
        header.getAny().add(objectFactory.createUserCertificateToken(userCertiticateToken));

        final Result authResult = authenticator.authenticate(newReq(header));
        Assert.assertNotNull(authResult);
        Assert.assertTrue(authResult.completed());
        Assert.assertEquals(principalIdc13d, authResult.getPrincipalId());
        Assert.assertEquals(Result.AuthnMethod.SMARTCARD, authResult.getAuthnMethod());

        EasyMock.verify(idmAuth);
    }

    private Request newReq(SecurityHeaderType header) {
        return new Request(header, new RequestSecurityTokenType(), null, null, null);
    }

    private static X509Certificate generateCertificate(KeyPair keyPair, String dn) throws Exception {
        ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withRSA").build(keyPair.getPrivate());

        Date startDate = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000);
        Date endDate = new Date(System.currentTimeMillis() + 365 * 24 * 60 * 60 * 1000);

        X509v3CertificateBuilder v3CertGen = new JcaX509v3CertificateBuilder(new X500Name("CN=" + dn),
                new BigInteger(64, new SecureRandom()), startDate, endDate, new X500Name("CN=" + dn),
                keyPair.getPublic());
        v3CertGen.addExtension(Extension.subjectAlternativeName, true,
                new GeneralNames(new GeneralName(GeneralName.otherName,
                        new DERSequence(new ASN1Encodable[] { new DERObjectIdentifier("1.3.6.1.4.1.311.20.2.3"),
                                new DERTaggedObject(true, 0, new DERUTF8String(upn)) }))));

        X509CertificateHolder certHolder = v3CertGen.build(sigGen);
        X509Certificate x509Certificate = new JcaX509CertificateConverter().getCertificate(certHolder);
        return x509Certificate;
    }
}