Example usage for org.bouncycastle.operator.jcajce JcaContentSignerBuilder JcaContentSignerBuilder

List of usage examples for org.bouncycastle.operator.jcajce JcaContentSignerBuilder JcaContentSignerBuilder

Introduction

In this page you can find the example usage for org.bouncycastle.operator.jcajce JcaContentSignerBuilder JcaContentSignerBuilder.

Prototype

public JcaContentSignerBuilder(String signatureAlgorithm) 

Source Link

Usage

From source file:org.pepstock.jem.node.security.keystore.SelfSignedCertificate.java

License:Open Source License

/**
 * Returns X.509 certificates programmatically leveraging on Bouncycastle lightweight API
 * @return certificate in byte array format
 * @throws KeyStoreException if any error occurs
 * @throws NoSuchAlgorithmException if any error occurs
 * @throws CertificateException if any error occurs
 * @throws IOException if any error occurs
 * @throws OperatorCreationException if any error occurs
 *///w ww. j  av  a  2s.  c o m
static ByteArrayInputStream getCertificate() throws NoSuchAlgorithmException, OperatorCreationException,
        CertificateException, KeyStoreException, IOException {
    // creates a key pair generator
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(CERTIFICATE_ALGORITHM);
    keyPairGenerator.initialize(CERTIFICATE_BITS, new SecureRandom());
    // creates a couple of keys
    KeyPair keyPair = keyPairGenerator.generateKeyPair();

    // GENERATE THE X509 CERTIFICATE
    X500Principal principal = new X500Principal(CERTIFICATE_DN);
    // sets times of certificate
    // starting from now
    long now = System.currentTimeMillis();
    Date notBefore = new Date(now - TimeUtils.DAY);
    Date notAfter = new Date(now + 10 * TimeUtils.DAY * 365);
    BigInteger serial = BigInteger.valueOf(now);

    // creaets a builder
    X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(principal, serial, notBefore, notAfter,
            principal, keyPair.getPublic());
    // creates the content signed by private key
    ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider("BC")
            .build(keyPair.getPrivate());
    // build certificate and convert in JCA
    X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC")
            .getCertificate(certGen.build(sigGen));
    return createKeyStore(cert, keyPair.getPrivate());
}

From source file:org.picketlink.pki.internal.util.X509Util.java

License:Open Source License

/**
 * Generate version 3 {@link java.security.cert.X509Certificate}.
 *
 * @param rootCertificate the root certificate
 * @param issuerKeyPair the issuer key pair
 * @param subjectDN the subject dn//  w  w  w. java2 s  . co  m
 * @param subjectKeyPair the subject key pair
 * @param certificateConfig the certificate config
 *
 * @return the x509 certificate
 */
public static X509Certificate generateV3Certificate(X509Certificate rootCertificate, KeyPair issuerKeyPair,
        X500Name subjectDN, KeyPair subjectKeyPair, CertificateAuthorityConfig certificateConfig) {
    try {
        // Serial Number
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        BigInteger serialNumber = BigInteger.valueOf(Math.abs(random.nextInt()));

        // Validity
        Date notBefore = new Date(System.currentTimeMillis());
        Date notAfter = new Date(System.currentTimeMillis() + (((1000L * 60 * 60 * 24 * 30)) * 12) * 3);

        // SubjectPublicKeyInfo
        SubjectPublicKeyInfo subjPubKeyInfo = new SubjectPublicKeyInfo(
                ASN1Sequence.getInstance(subjectKeyPair.getPublic().getEncoded()));

        X509v3CertificateBuilder certGen = new X509v3CertificateBuilder(
                new X500Name(rootCertificate.getSubjectDN().getName()), serialNumber, notBefore, notAfter,
                subjectDN, subjPubKeyInfo);

        DigestCalculator digCalc = new BcDigestCalculatorProvider()
                .get(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1));
        X509ExtensionUtils x509ExtensionUtils = new X509ExtensionUtils(digCalc);

        // Subject Key Identifier
        certGen.addExtension(Extension.subjectKeyIdentifier, false,
                x509ExtensionUtils.createSubjectKeyIdentifier(subjPubKeyInfo));

        // Authority Key Identifier
        certGen.addExtension(Extension.authorityKeyIdentifier, false,
                x509ExtensionUtils.createAuthorityKeyIdentifier(subjPubKeyInfo));

        // Key Usage
        certGen.addExtension(Extension.keyUsage, false,
                new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign));

        // Extended Key Usage
        KeyPurposeId[] EKU = new KeyPurposeId[2];
        EKU[0] = KeyPurposeId.id_kp_emailProtection;
        EKU[1] = KeyPurposeId.id_kp_serverAuth;

        certGen.addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(EKU));

        // Basic Constraints
        certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0));

        // Certificate Policies
        /* PolicyInformation[] certPolicies = new PolicyInformation[2];
        certPolicies[0] = new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.2.1.11.5"));
        certPolicies[1] = new PolicyInformation(new ASN1ObjectIdentifier("2.16.840.1.101.2.1.11.18"));
                
        certGen.addExtension(Extension.certificatePolicies, false, new CertificatePolicies(certPolicies));
                
        // Authority Information Access
        AccessDescription caIssuers = new AccessDescription(AccessDescription.id_ad_caIssuers, new GeneralName(
            GeneralName.uniformResourceIdentifier, new DERIA5String("http://www.somewebsite.com/ca.cer")));
        AccessDescription ocsp = new AccessDescription(AccessDescription.id_ad_ocsp, new GeneralName(
            GeneralName.uniformResourceIdentifier, new DERIA5String("http://ocsp.somewebsite.com")));
                
        ASN1EncodableVector aia_ASN = new ASN1EncodableVector();
        aia_ASN.add(caIssuers);
        aia_ASN.add(ocsp);
                
        certGen.addExtension(Extension.authorityInfoAccess, false, new DERSequence(aia_ASN));
                
        // CRL Distribution Points
        DistributionPointName distPointOne = new DistributionPointName(new GeneralNames(new GeneralName(
            GeneralName.uniformResourceIdentifier, "http://crl.somewebsite.com/master.crl")));
        DistributionPointName distPointTwo = new DistributionPointName(
            new GeneralNames(
                    new GeneralName(GeneralName.uniformResourceIdentifier,
                            "ldap://crl.somewebsite.com/cn%3dSecureCA%2cou%3dPKI%2co%3dCyberdyne%2cc%3dUS?certificaterevocationlist;binary")));
                
        DistributionPoint[] distPoints = new DistributionPoint[2];
        distPoints[0] = new DistributionPoint(distPointOne, null, null);
        distPoints[1] = new DistributionPoint(distPointTwo, null, null);
                
        certGen.addExtension(Extension.cRLDistributionPoints, false, new CRLDistPoint(distPoints));*/

        // Content Signer
        ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider("BC")
                .build(issuerKeyPair.getPrivate());

        // Certificate
        return new JcaX509CertificateConverter().setProvider("BC").getCertificate(certGen.build(sigGen));
    } catch (Exception e) {
        throw new RuntimeException("Error creating X509v3Certificate.", e);
    }
}

From source file:org.primeoservices.cfpass.PassUtils.java

License:Apache License

public static void createSignature(final String directoryPath, final String keyStoreFilePath,
        final String keyStorePassword) throws Exception {
    // Add BC provider
    if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
        Security.addProvider(new BouncyCastleProvider());
    }/*from  w w w .ja va2 s .c  o  m*/

    // Check directory
    final File directory = new File(directoryPath);
    if (directory.exists() && !directory.isDirectory()) {
        throw new IllegalArgumentException(directoryPath + " is not a directory");
    }

    // Check manifest file
    final File manifest = new File(directory, "manifest.json");
    if (manifest.exists() && !manifest.isFile()) {
        throw new IllegalArgumentException("File manifest.json doesn't exists");
    }

    // Check key store
    final File keyStore = new File(keyStoreFilePath);
    if (keyStore.exists() && !keyStore.isFile()) {
        throw new IllegalArgumentException("Keystore not found");
    }

    // Load key store
    final FileInputStream clientStoreIn = new FileInputStream(keyStore);
    final KeyStore clientStore = KeyStore.getInstance("PKCS12");
    clientStore.load(clientStoreIn, keyStorePassword.toCharArray());

    // Extract private key and certificate
    final Enumeration<String> aliases = clientStore.aliases();
    String alias = "";
    while (aliases.hasMoreElements()) {
        alias = aliases.nextElement();
        if (clientStore.isKeyEntry(alias)) {
            break;
        }
    }
    final PrivateKey key = (PrivateKey) clientStore.getKey(alias, keyStorePassword.toCharArray());
    final X509Certificate cert = (X509Certificate) clientStore.getCertificate(alias);

    // Load Apple certificate
    final InputStream appleCertIn = PassUtils.class.getResourceAsStream("/AppleWWDRCA.cer");
    final CertificateFactory appleCertFactory = CertificateFactory.getInstance("X.509");
    final X509Certificate appleCert = (X509Certificate) appleCertFactory.generateCertificate(appleCertIn);

    // Signature
    final ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA")
            .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(key);

    final ASN1EncodableVector signedAttributes = new ASN1EncodableVector();
    final Attribute signingAttribute = new Attribute(CMSAttributes.signingTime,
            new DERSet(new DERUTCTime(new Date())));
    signedAttributes.add(signingAttribute);
    // Create the signing table
    final AttributeTable signedAttributesTable = new AttributeTable(signedAttributes);
    // Create the table table generator that will added to the Signer builder
    final DefaultSignedAttributeTableGenerator signedAttributeGenerator = new DefaultSignedAttributeTableGenerator(
            signedAttributesTable);

    List<X509Certificate> certList = new ArrayList<X509Certificate>();
    certList.add(appleCert);
    certList.add(cert);
    Store certs = new JcaCertStore(certList);

    final CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
    generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
            new JcaDigestCalculatorProviderBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME).build())
                    .setSignedAttributeGenerator(signedAttributeGenerator).build(sha1Signer, cert));
    generator.addCertificates(certs);

    final CMSSignedData sigData = generator.generate(new CMSProcessableFile(manifest), false);
    final byte[] signedDataBytes = sigData.getEncoded();

    // Write signature
    final File signatureFile = new File(directoryPath, "signature");
    final FileOutputStream signatureOutputStream = new FileOutputStream(signatureFile);
    signatureOutputStream.write(signedDataBytes);
    signatureOutputStream.close();
}

From source file:org.roda.common.certification.SignatureUtility.java

/**
 * Initialize parameters for signing/* w  ww  .  j av  a 2 s . c o m*/
 * 
 * @param alias
 *          private key alias
 * 
 * @param password
 *          the keystore password
 * @throws KeyStoreException
 * @throws NoSuchAlgorithmException
 * @throws UnrecoverableKeyException
 * @throws OperatorCreationException
 * @throws CertificateEncodingException
 * @throws CMSException
 */
public void initSign(String alias, char[] password) throws UnrecoverableKeyException, KeyStoreException,
        NoSuchAlgorithmException, CertificateEncodingException, OperatorCreationException, CMSException {
    PrivateKey pk = (PrivateKey) ks.getKey(alias, password);
    Certificate[] certificateChain = ks.getCertificateChain(alias);
    if (certificateChain != null) {
        X509Certificate certificate = (X509Certificate) certificateChain[0];
        List<Certificate> certList = new ArrayList<Certificate>(Arrays.asList(certificateChain));

        signGenerator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
                new JcaDigestCalculatorProviderBuilder().setProvider(SIGN_PROVIDER).build()).build(
                        new JcaContentSignerBuilder(SIGN_ALGORITHM).setProvider(SIGN_PROVIDER).build(pk),
                        certificate));

        JcaCertStore certs = new JcaCertStore(certList);
        signGenerator.addCertificates(certs);

    } else {
        System.err.println("Certificate chain for " + alias + " not found");
    }
}

From source file:org.shredzone.acme4j.util.CertificateUtils.java

License:Apache License

/**
 * Creates a self-signed {@link X509Certificate} that can be used for
 * {@link org.shredzone.acme4j.challenge.TlsSni01Challenge}. The certificate is valid
 * for 7 days./*from w ww  .  j av  a  2  s.c  o m*/
 *
 * @param keypair
 *            A domain {@link KeyPair} to be used for the challenge
 * @param subject
 *            Subject to create a certificate for
 * @return Created certificate
 * @deprecated Will be removed when
 *             {@link org.shredzone.acme4j.challenge.TlsSni01Challenge} is removed
 */
@Deprecated
public static X509Certificate createTlsSniCertificate(KeyPair keypair, String subject) throws IOException {
    final long now = System.currentTimeMillis();
    final long validSpanMs = 7 * 24 * 60 * 60 * 1000L;
    final String signatureAlg = "SHA256withRSA";

    try {
        X500Name issuer = new X500Name("CN=acme.invalid");
        BigInteger serial = BigInteger.valueOf(now);
        Date notBefore = new Date(now);
        Date notAfter = new Date(now + validSpanMs);

        JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(issuer, serial, notBefore,
                notAfter, issuer, keypair.getPublic());

        GeneralName[] gns = new GeneralName[1];
        gns[0] = new GeneralName(GeneralName.dNSName, subject);

        certBuilder.addExtension(Extension.subjectAlternativeName, false, new GeneralNames(gns));

        JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(signatureAlg);

        byte[] cert = certBuilder.build(signerBuilder.build(keypair.getPrivate())).getEncoded();

        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        return (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(cert));
    } catch (CertificateException | OperatorCreationException ex) {
        throw new IOException(ex);
    }
}

From source file:org.shredzone.acme4j.util.CertificateUtils.java

License:Apache License

/**
 * Creates a self-signed {@link X509Certificate} that can be used for
 * {@link TlsSni02Challenge}. The certificate is valid for 7 days.
 *
 * @param keypair/*from ww w  . j  av  a 2 s.  c  o m*/
 *            A domain {@link KeyPair} to be used for the challenge
 * @param sanA
 *            SAN-A to be used in the certificate
 * @param sanB
 *            SAN-B to be used in the certificate
 * @return Created certificate
 */
public static X509Certificate createTlsSni02Certificate(KeyPair keypair, String sanA, String sanB)
        throws IOException {
    final long now = System.currentTimeMillis();
    final long validSpanMs = 7 * 24 * 60 * 60 * 1000L;
    final String signatureAlg = "SHA256withRSA";

    try {
        X500Name issuer = new X500Name("CN=acme.invalid");
        BigInteger serial = BigInteger.valueOf(now);
        Date notBefore = new Date(now);
        Date notAfter = new Date(now + validSpanMs);

        JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(issuer, serial, notBefore,
                notAfter, issuer, keypair.getPublic());

        GeneralName[] gns = new GeneralName[2];
        gns[0] = new GeneralName(GeneralName.dNSName, sanA);
        gns[1] = new GeneralName(GeneralName.dNSName, sanB);

        certBuilder.addExtension(Extension.subjectAlternativeName, false, new GeneralNames(gns));

        JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(signatureAlg);

        byte[] cert = certBuilder.build(signerBuilder.build(keypair.getPrivate())).getEncoded();

        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        return (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(cert));
    } catch (CertificateException | OperatorCreationException ex) {
        throw new IOException(ex);
    }
}

From source file:org.shredzone.acme4j.util.CSRBuilder.java

License:Apache License

/**
 * Signs the completed CSR.//from   w  w  w  . java 2  s  .co  m
 *
 * @param keypair
 *            {@link KeyPair} to sign the CSR with
 */
public void sign(KeyPair keypair) throws IOException {
    if (namelist.isEmpty()) {
        throw new IllegalStateException("No domain was set");
    }
    if (keypair == null) {
        throw new IllegalArgumentException("keypair must not be null");
    }

    try {
        GeneralName[] gns = new GeneralName[namelist.size()];
        for (int ix = 0; ix < namelist.size(); ix++) {
            gns[ix] = new GeneralName(GeneralName.dNSName, namelist.get(ix));
        }
        GeneralNames subjectAltName = new GeneralNames(gns);

        PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(
                namebuilder.build(), keypair.getPublic());

        ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
        extensionsGenerator.addExtension(Extension.subjectAlternativeName, false, subjectAltName);
        p10Builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest,
                extensionsGenerator.generate());

        PrivateKey pk = keypair.getPrivate();
        JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder(
                pk instanceof ECKey ? EC_SIGNATURE_ALG : SIGNATURE_ALG);
        ContentSigner signer = csBuilder.build(pk);

        csr = p10Builder.build(signer);
    } catch (OperatorCreationException ex) {
        throw new IOException("Could not generate CSR", ex);
    }
}

From source file:org.signserver.module.cmssigner.CMSSigner.java

License:Open Source License

@Override
public ProcessResponse processData(final ProcessRequest signRequest, final RequestContext requestContext)
        throws IllegalRequestException, org.signserver.common.CryptoTokenOfflineException, SignServerException {

    ProcessResponse signResponse;//  ww w.  j a va2  s . c  o  m

    // Check that the request contains a valid GenericSignRequest object
    // with a byte[].
    if (!(signRequest instanceof GenericSignRequest)) {
        throw new IllegalRequestException("Recieved request wasn't a expected GenericSignRequest.");
    }

    final ISignRequest sReq = (ISignRequest) signRequest;

    if (!(sReq.getRequestData() instanceof byte[])) {
        throw new IllegalRequestException("Recieved request data wasn't a expected byte[].");
    }

    if (!configErrors.isEmpty()) {
        throw new SignServerException("Worker is misconfigured");
    }

    byte[] data = (byte[]) sReq.getRequestData();
    final String archiveId = createArchiveId(data, (String) requestContext.get(RequestContext.TRANSACTION_ID));

    ICryptoInstance crypto = null;
    try {
        crypto = acquireCryptoInstance(ICryptoToken.PURPOSE_SIGN, signRequest, requestContext);
        final X509Certificate cert = (X509Certificate) getSigningCertificate(crypto);
        if (LOG.isDebugEnabled()) {
            LOG.debug("SigningCert: " + cert);
        }

        // Get certificate chain and signer certificate
        final List<Certificate> certs = this.getSigningCertificateChain(crypto);
        if (certs == null) {
            throw new IllegalArgumentException("Null certificate chain. This signer needs a certificate.");
        }

        final CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
        final String sigAlg = signatureAlgorithm == null ? getDefaultSignatureAlgorithm(crypto.getPublicKey())
                : signatureAlgorithm;
        final ContentSigner contentSigner = new JcaContentSignerBuilder(sigAlg)
                .setProvider(crypto.getProvider()).build(crypto.getPrivateKey());
        generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
                new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(contentSigner, cert));

        generator.addCertificates(new JcaCertStore(includedCertificates(certs)));
        final CMSTypedData content = new CMSProcessableByteArray(data);

        // Should the content be detached or not
        final boolean detached;
        final Boolean detachedRequested = getDetachedSignatureRequest(requestContext);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Detached signature configured: " + detachedSignature + "\n"
                    + "Detached signature requested: " + detachedRequested);
        }
        if (detachedRequested == null) {
            detached = detachedSignature;
        } else {
            if (detachedRequested) {
                if (!detachedSignature && !allowDetachedSignatureOverride) {
                    throw new IllegalRequestException("Detached signature requested but not allowed");
                }
            } else {
                if (detachedSignature && !allowDetachedSignatureOverride) {
                    throw new IllegalRequestException("Non detached signature requested but not allowed");
                }
            }
            detached = detachedRequested;
        }

        final CMSSignedData signedData = generator.generate(content, !detached);

        final byte[] signedbytes = signedData.getEncoded();
        final Collection<? extends Archivable> archivables = Arrays
                .asList(new DefaultArchivable(Archivable.TYPE_RESPONSE, CONTENT_TYPE, signedbytes, archiveId));

        if (signRequest instanceof GenericServletRequest) {
            signResponse = new GenericServletResponse(sReq.getRequestID(), signedbytes,
                    getSigningCertificate(signRequest, requestContext), archiveId, archivables, CONTENT_TYPE);
        } else {
            signResponse = new GenericSignResponse(sReq.getRequestID(), signedbytes,
                    getSigningCertificate(signRequest, requestContext), archiveId, archivables);
        }

        // Suggest new file name
        final Object fileNameOriginal = requestContext.get(RequestContext.FILENAME);
        if (fileNameOriginal instanceof String) {
            requestContext.put(RequestContext.RESPONSE_FILENAME, fileNameOriginal + ".p7s");
        }

        // The client can be charged for the request
        requestContext.setRequestFulfilledByWorker(true);

        return signResponse;
    } catch (OperatorCreationException ex) {
        LOG.error("Error initializing signer", ex);
        throw new SignServerException("Error initializing signer", ex);
    } catch (CertificateEncodingException ex) {
        LOG.error("Error constructing cert store", ex);
        throw new SignServerException("Error constructing cert store", ex);
    } catch (CMSException ex) {
        LOG.error("Error constructing CMS", ex);
        throw new SignServerException("Error constructing CMS", ex);
    } catch (IOException ex) {
        LOG.error("Error constructing CMS", ex);
        throw new SignServerException("Error constructing CMS", ex);
    } finally {
        releaseCryptoInstance(crypto, requestContext);
    }
}

From source file:org.signserver.module.pdfsigner.PDFSignerUnitTest.java

License:Open Source License

private X509CRL createCRL(PrivateKey caCrlPrivKey, byte[] data) throws Exception {
    X509v2CRLBuilder crlGen = new X509v2CRLBuilder(new X500Name("CN=CRL Issuer"), new Date());
    crlGen.addCRLEntry(BigInteger.ONE, new Date(), CRLReason.privilegeWithdrawn);
    crlGen.addExtension(new ASN1ObjectIdentifier("1.2.3.4"), false, new DERBitString(data));
    X509CRLHolder crl = crlGen.build(new JcaContentSignerBuilder("SHA1withRSA").build(caCrlPrivKey));
    return new JcaX509CRLConverter().getCRL(crl);
}

From source file:org.signserver.module.tsa.MSAuthCodeTimeStampSigner.java

License:Open Source License

/**
 * The main method performing the actual timestamp operation.
 * Expects the signRequest to be a GenericSignRequest contining a
 * TimeStampRequest//from  ww w.j  a v a 2  s.  com
 *
 * @param signRequest
 * @param requestContext
 * @return the sign response
 * @see org.signserver.server.IProcessable#processData(org.signserver.common.ProcessRequest, org.signserver.common.RequestContext)
 */
public ProcessResponse processData(final ProcessRequest signRequest, final RequestContext requestContext)
        throws IllegalRequestException, CryptoTokenOfflineException, SignServerException {

    // Log values
    final LogMap logMap = LogMap.getInstance(requestContext);

    try {
        final ISignRequest sReq = (ISignRequest) signRequest;
        final byte[] requestbytes = (byte[]) sReq.getRequestData();

        if (requestbytes == null || requestbytes.length == 0) {
            LOG.error("Request must contain data");
            throw new IllegalRequestException("Request must contain data");
        }

        // Check that the request contains a valid TimeStampRequest object.
        if (!(signRequest instanceof GenericSignRequest)) {
            final IllegalRequestException exception = new IllegalRequestException(
                    "Recieved request wasn't an expected GenericSignRequest. ");
            LOG.error("Received request wasn't an expected GenericSignRequest");
            throw exception;
        }

        if (!((sReq.getRequestData() instanceof TimeStampRequest)
                || (sReq.getRequestData() instanceof byte[]))) {
            final IllegalRequestException exception = new IllegalRequestException(
                    "Recieved request data wasn't an expected TimeStampRequest. ");
            LOG.error("Received request data wasn't an expected TimeStampRequest");
            throw exception;
        }

        if (!validChain) {
            LOG.error("Certificate chain not correctly configured");
            throw new CryptoTokenOfflineException("Certificate chain not correctly configured");
        }

        ASN1Primitive asn1obj = ASN1Primitive.fromByteArray(Base64.decode(requestbytes));
        ASN1Sequence asn1seq = ASN1Sequence.getInstance(asn1obj);

        if (asn1seq.size() != 2) {
            LOG.error("Wrong structure, should be an ASN1Sequence with 2 elements");
            throw new IllegalRequestException("Wrong structure, should be an ASN1Sequence with 2 elements");
        }

        ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(asn1seq.getObjectAt(0));
        ASN1Sequence asn1seq1 = ASN1Sequence.getInstance(asn1seq.getObjectAt(1));

        final ContentInfo ci = new ContentInfo(asn1seq1);

        if (!oid.getId().equals(msOID)) {
            LOG.error("Invalid OID in request: " + oid.getId());
            throw new IllegalRequestException("Invalid OID in request: " + oid.getId());
        }

        if (asn1seq1.size() != 2) {
            LOG.error(
                    "Wrong structure, should be an ASN1Sequence with 2 elements as the value of element 0 in the outer ASN1Sequence");
            throw new IllegalRequestException(
                    "Wrong structure, should be an ASN1Sequence with 2 elements as the value of element 0 in the outer ASN1Sequence");
        }

        oid = ASN1ObjectIdentifier.getInstance(asn1seq1.getObjectAt(0));

        if (!oid.getId().equals(dataOID)) {
            throw new IllegalRequestException("Wrong contentType OID: " + oid.getId());
        }

        ASN1TaggedObject tag = ASN1TaggedObject.getInstance(asn1seq1.getObjectAt(1));

        if (tag.getTagNo() != 0) {
            throw new IllegalRequestException("Wrong tag no (should be 0): " + tag.getTagNo());
        }

        ASN1OctetString octets = ASN1OctetString.getInstance(tag.getObject());
        byte[] content = octets.getOctets();

        final ITimeSource timeSrc;
        final Date date;
        byte[] der;
        ICryptoInstance crypto = null;
        try {
            crypto = acquireCryptoInstance(ICryptoToken.PURPOSE_SIGN, signRequest, requestContext);

            // get signing cert certificate chain and private key
            List<Certificate> certList = this.getSigningCertificateChain(crypto);
            if (certList == null) {
                throw new SignServerException("Null certificate chain. This signer needs a certificate.");
            }

            Certificate[] certs = (Certificate[]) certList.toArray(new Certificate[certList.size()]);

            // Sign
            X509Certificate x509cert = (X509Certificate) certs[0];

            timeSrc = getTimeSource();
            if (LOG.isDebugEnabled()) {
                LOG.debug("TimeSource: " + timeSrc.getClass().getName());
            }
            date = timeSrc.getGenTime();

            if (date == null) {
                throw new ServiceUnavailableException("Time source is not available");
            }

            ASN1EncodableVector signedAttributes = new ASN1EncodableVector();
            signedAttributes.add(new Attribute(CMSAttributes.signingTime, new DERSet(new Time(date))));

            if (includeSigningCertificateAttribute) {
                try {
                    final DERInteger serial = new DERInteger(x509cert.getSerialNumber());
                    final X509CertificateHolder certHolder = new X509CertificateHolder(x509cert.getEncoded());
                    final X500Name issuer = certHolder.getIssuer();
                    final GeneralName name = new GeneralName(issuer);
                    final GeneralNames names = new GeneralNames(name);
                    final IssuerSerial is = new IssuerSerial(names, ASN1Integer.getInstance(serial));

                    final ESSCertID essCertid = new ESSCertID(
                            MessageDigest.getInstance("SHA-1").digest(x509cert.getEncoded()), is);
                    signedAttributes.add(new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificate,
                            new DERSet(new SigningCertificate(essCertid))));
                } catch (NoSuchAlgorithmException e) {
                    LOG.error("Can't find SHA-1 implementation: " + e.getMessage());
                    throw new SignServerException("Can't find SHA-1 implementation", e);
                }
            }

            AttributeTable signedAttributesTable = new AttributeTable(signedAttributes);
            DefaultSignedAttributeTableGenerator signedAttributeGenerator = new DefaultSignedAttributeTableGenerator(
                    signedAttributesTable);

            final String provider = cryptoToken.getProvider(ICryptoToken.PROVIDERUSAGE_SIGN);

            SignerInfoGeneratorBuilder signerInfoBuilder = new SignerInfoGeneratorBuilder(
                    new JcaDigestCalculatorProviderBuilder().setProvider("BC").build());
            signerInfoBuilder.setSignedAttributeGenerator(signedAttributeGenerator);

            JcaContentSignerBuilder contentSigner = new JcaContentSignerBuilder(signatureAlgo);
            contentSigner.setProvider(provider);

            final SignerInfoGenerator sig = signerInfoBuilder.build(contentSigner.build(crypto.getPrivateKey()),
                    new X509CertificateHolder(x509cert.getEncoded()));

            JcaCertStore cs = new JcaCertStore(certList);

            CMSTypedData cmspba = new CMSProcessableByteArray(content);
            CMSSignedData cmssd = MSAuthCodeCMSUtils.generate(cmspba, true, Arrays.asList(sig),
                    MSAuthCodeCMSUtils.getCertificatesFromStore(cs), Collections.emptyList(), ci);

            der = ASN1Primitive.fromByteArray(cmssd.getEncoded()).getEncoded();
        } finally {
            releaseCryptoInstance(crypto, requestContext);
        }

        // Log values
        logMap.put(ITimeStampLogger.LOG_TSA_TIME, String.valueOf(date.getTime()));
        logMap.put(ITimeStampLogger.LOG_TSA_TIMESOURCE, timeSrc.getClass().getSimpleName());

        final String archiveId = createArchiveId(requestbytes,
                (String) requestContext.get(RequestContext.TRANSACTION_ID));

        final GenericSignResponse signResponse;
        byte[] signedbytes = Base64.encode(der, false);

        logMap.put(ITimeStampLogger.LOG_TSA_TIMESTAMPRESPONSE_ENCODED, new String(signedbytes));

        final Collection<? extends Archivable> archivables = Arrays.asList(
                new DefaultArchivable(Archivable.TYPE_REQUEST, REQUEST_CONTENT_TYPE, requestbytes, archiveId),
                new DefaultArchivable(Archivable.TYPE_RESPONSE, RESPONSE_CONTENT_TYPE, signedbytes, archiveId));

        if (signRequest instanceof GenericServletRequest) {
            signResponse = new GenericServletResponse(sReq.getRequestID(), signedbytes,
                    getSigningCertificate(signRequest, requestContext), archiveId, archivables,
                    RESPONSE_CONTENT_TYPE);
        } else {
            signResponse = new GenericSignResponse(sReq.getRequestID(), signedbytes,
                    getSigningCertificate(signRequest, requestContext), archiveId, archivables);
        }

        // The client can be charged for the request
        requestContext.setRequestFulfilledByWorker(true);

        return signResponse;

    } catch (IOException e) {
        final IllegalRequestException exception = new IllegalRequestException("IOException: " + e.getMessage(),
                e);
        LOG.error("IOException: ", e);
        logMap.put(ITimeStampLogger.LOG_TSA_EXCEPTION, exception.getMessage());
        throw exception;
    } catch (CMSException e) {
        final SignServerException exception = new SignServerException(e.getMessage(), e);
        LOG.error("CMSException: ", e);
        logMap.put(ITimeStampLogger.LOG_TSA_EXCEPTION, exception.getMessage());
        throw exception;
    } catch (OperatorCreationException e) {
        final SignServerException exception = new SignServerException(e.getMessage(), e);
        LOG.error("OperatorCreationException: ", e);
        logMap.put(ITimeStampLogger.LOG_TSA_EXCEPTION, exception.getMessage());
        throw exception;
    } catch (CertificateEncodingException e) {
        final SignServerException exception = new SignServerException(e.getMessage(), e);
        LOG.error("CertificateEncodingException: ", e);
        logMap.put(ITimeStampLogger.LOG_TSA_EXCEPTION, exception.getMessage());
        throw exception;
    } catch (ArrayIndexOutOfBoundsException e) {
        // the BC base64 decoder doesn't check the the base64 input length...
        final IllegalRequestException exception = new IllegalRequestException(
                "ArrayIndexOutOfBoundsException: " + e.getMessage(), e);
        LOG.error("ArrayIndexOutOfBoundsException: ", e);
        logMap.put(ITimeStampLogger.LOG_TSA_EXCEPTION, exception.getMessage());
        throw exception;
    }
}