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

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

Introduction

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

Prototype

public JcaDigestCalculatorProviderBuilder() 

Source Link

Usage

From source file:org.jruby.ext.openssl.OCSPBasicResponse.java

License:Common Public License

@JRubyMethod(name = "sign", rest = true)
public IRubyObject sign(final ThreadContext context, IRubyObject[] args) {
    Ruby runtime = context.getRuntime();

    int flag = 0;
    IRubyObject additionalCerts = context.nil;
    IRubyObject flags = context.nil;/*from  www  .  j av a 2s .  co  m*/
    IRubyObject digest = context.nil;
    Digest digestInstance = new Digest(runtime, _Digest(runtime));
    List<X509CertificateHolder> addlCerts = new ArrayList<X509CertificateHolder>();

    switch (Arity.checkArgumentCount(runtime, args, 2, 5)) {
    case 3:
        additionalCerts = args[2];
        break;
    case 4:
        additionalCerts = args[2];
        flags = args[3];
        break;
    case 5:
        additionalCerts = args[2];
        flags = args[3];
        digest = args[4];
        break;
    default:
        break;
    }

    if (digest.isNil())
        digest = digestInstance.initialize(context,
                new IRubyObject[] { RubyString.newString(runtime, "SHA1") });
    if (!flags.isNil())
        flag = RubyFixnum.fix2int(flags);
    if (additionalCerts.isNil())
        flag |= RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOCERTS));

    X509Cert signer = (X509Cert) args[0];
    PKey signerKey = (PKey) args[1];

    String keyAlg = signerKey.getAlgorithm();
    String digAlg = ((Digest) digest).getShortAlgorithm();

    JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(digAlg + "with" + keyAlg);
    signerBuilder.setProvider("BC");
    ContentSigner contentSigner = null;
    try {
        contentSigner = signerBuilder.build(signerKey.getPrivateKey());
    } catch (OperatorCreationException e) {
        throw newOCSPError(runtime, e);
    }

    BasicOCSPRespBuilder respBuilder = null;
    try {
        if ((flag & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_RESPID_KEY))) != 0) {
            JcaDigestCalculatorProviderBuilder dcpb = new JcaDigestCalculatorProviderBuilder();
            dcpb.setProvider("BC");
            DigestCalculatorProvider dcp = dcpb.build();
            DigestCalculator calculator = dcp.get(contentSigner.getAlgorithmIdentifier());
            respBuilder = new BasicOCSPRespBuilder(
                    SubjectPublicKeyInfo.getInstance(signerKey.getPublicKey().getEncoded()), calculator);
        } else {
            respBuilder = new BasicOCSPRespBuilder(new RespID(signer.getSubject().getX500Name()));
        }
    } catch (Exception e) {
        throw newOCSPError(runtime, e);
    }

    X509CertificateHolder[] chain = null;
    try {
        if ((flag & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOCERTS))) == 0) {
            addlCerts.add(new X509CertificateHolder(signer.getAuxCert().getEncoded()));
            if (!additionalCerts.isNil()) {
                Iterator<java.security.cert.Certificate> rubyAddlCerts = ((RubyArray) additionalCerts)
                        .iterator();
                while (rubyAddlCerts.hasNext()) {
                    java.security.cert.Certificate cert = rubyAddlCerts.next();
                    addlCerts.add(new X509CertificateHolder(cert.getEncoded()));
                }
            }

            chain = addlCerts.toArray(new X509CertificateHolder[addlCerts.size()]);
        }
    } catch (Exception e) {
        throw newOCSPError(runtime, e);
    }

    Date producedAt = null;
    if ((flag & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOTIME))) == 0) {
        producedAt = new Date();
    }

    for (OCSPSingleResponse resp : singleResponses) {
        SingleResp singleResp = new SingleResp(resp.getBCSingleResp());
        respBuilder.addResponse(singleResp.getCertID(), singleResp.getCertStatus(), singleResp.getThisUpdate(),
                singleResp.getNextUpdate(), resp.getBCSingleResp().getSingleExtensions());
    }

    try {
        Extension[] respExtAry = new Extension[extensions.size()];
        Extensions respExtensions = new Extensions(extensions.toArray(respExtAry));
        BasicOCSPResp bcBasicOCSPResp = respBuilder.setResponseExtensions(respExtensions).build(contentSigner,
                chain, producedAt);
        asn1BCBasicOCSPResp = BasicOCSPResponse.getInstance(bcBasicOCSPResp.getEncoded());
    } catch (Exception e) {
        throw newOCSPError(runtime, e);
    }
    return this;
}

From source file:org.jscep.message.PkiMessageEncoder.java

License:Open Source License

private DigestCalculatorProvider getDigestCalculator() throws MessageEncodingException {
    try {/*from   ww w. j a  v a 2 s  .  c  o  m*/
        return new JcaDigestCalculatorProviderBuilder().build();
    } catch (OperatorCreationException e) {
        throw new MessageEncodingException(e);
    }
}

From source file:org.jscep.server.ScepServlet.java

License:Open Source License

private void doGetNextCaCert(final HttpServletRequest req, final HttpServletResponse res) throws Exception {
    res.setHeader("Content-Type", "application/x-x509-next-ca-cert");

    List<X509Certificate> certs = getNextCaCertificate(req.getParameter(MSG_PARAM));

    if (certs.size() == 0) {
        res.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "GetNextCACert Not Supported");
    } else {/*from   ww  w  .j av  a  2 s.c om*/
        CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
        JcaCertStore store;
        try {
            store = new JcaCertStore(certs);
        } catch (CertificateEncodingException e) {
            IOException ioe = new IOException();
            ioe.initCause(e);

            throw ioe;
        }
        generator.addCertificates(store);
        DigestCalculatorProvider digestProvider = new JcaDigestCalculatorProviderBuilder().build();
        SignerInfoGeneratorBuilder infoGenBuilder = new SignerInfoGeneratorBuilder(digestProvider);
        X509CertificateHolder certHolder = new X509CertificateHolder(getRecipient().getEncoded());
        ContentSigner contentSigner = new JcaContentSignerBuilder("SHA1withRSA").build(getRecipientKey());
        SignerInfoGenerator infoGen = infoGenBuilder.build(contentSigner, certHolder);
        generator.addSignerInfoGenerator(infoGen);

        CMSSignedData degenerateSd = generator.generate(new CMSAbsentContent());
        byte[] bytes = degenerateSd.getEncoded();

        res.getOutputStream().write(bytes);
        res.getOutputStream().close();
    }
}

From source file:org.keycloak.testsuite.forms.x509.OcspHandler.java

License:Open Source License

@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    if (exchange.isInIoThread()) {
        exchange.dispatch(this);
        return;//ww w. j a v  a  2s .c o  m
    }

    final byte[] buffy = new byte[16384];
    try (InputStream requestStream = exchange.getInputStream()) {
        requestStream.read(buffy);
    }

    final OCSPReq request = new OCSPReq(buffy);
    final Req[] requested = request.getRequestList();

    final Extension nonce = request.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);

    final DigestCalculator sha1Calculator = new JcaDigestCalculatorProviderBuilder().build()
            .get(AlgorithmIdentifier.getInstance(RespID.HASH_SHA1));

    final BasicOCSPRespBuilder responseBuilder = new BasicOCSPRespBuilder(subjectPublicKeyInfo, sha1Calculator);

    if (nonce != null) {
        responseBuilder.setResponseExtensions(new Extensions(nonce));
    }

    for (final Req req : requested) {
        final CertificateID certId = req.getCertID();

        final BigInteger certificateSerialNumber = certId.getSerialNumber();
        responseBuilder.addResponse(certId, REVOKED_CERTIFICATES_STATUS.get(certificateSerialNumber));
    }

    final ContentSigner contentSigner = new BcRSAContentSignerBuilder(
            new AlgorithmIdentifier(PKCSObjectIdentifiers.sha256WithRSAEncryption),
            new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256)).build(privateKey);

    final OCSPResp response = new OCSPRespBuilder().build(OCSPResp.SUCCESSFUL,
            responseBuilder.build(contentSigner, chain, new Date()));

    final byte[] responseBytes = response.getEncoded();

    final HeaderMap responseHeaders = exchange.getResponseHeaders();
    responseHeaders.put(Headers.CONTENT_TYPE, "application/ocsp-response");

    final Sender responseSender = exchange.getResponseSender();
    responseSender.send(ByteBuffer.wrap(responseBytes));

    exchange.endExchange();
}

From source file:org.poreid.verify.ocsp.OCSPClient.java

License:Open Source License

private OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber)
        throws CertificateEncodingException, OperatorCreationException, OCSPException, IOException {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

    OCSPReqBuilder gen = new OCSPReqBuilder();
    gen.addRequest(new JcaCertificateID(
            new JcaDigestCalculatorProviderBuilder().setProvider("BC").build().get(CertificateID.HASH_SHA1),
            issuerCert, serialNumber));/*from ww  w  .  j  a v a  2s.co  m*/

    BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
    Extension ext = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, true,
            new DEROctetString(nonce.toByteArray()));
    gen.setRequestExtensions(new Extensions(new Extension[] { ext }));
    sentNonce = ext.getExtnId().getEncoded();

    return gen.build();
}

From source file:org.poreid.verify.sod.SOD.java

License:Open Source License

protected boolean verify() throws SODException {
    try {/*from  ww w  . j av  a 2 s  .c  om*/
        /* verificar caminho de certificao sem ocsp/crl, aqui no  local para essas consideraes */
        X509CertificateHolder holder = (X509CertificateHolder) cms.getCertificates().getMatches(null).iterator()
                .next(); // apenas o primeiro certificado (s tem 1)
        X509Certificate cert = (X509Certificate) get(holder.getEncoded());

        SignerInformationStore signerInformationStore = cms.getSignerInfos();
        SignerInformation signerInformation = (SignerInformation) signerInformationStore.getSigners().iterator()
                .next(); // apenas 1 assinatura (s tem 1)

        if (!Util.isLeafCertificateValid(keystore, cert)) {
            return false;
        }

        /* verificar assinatura do cms */
        ContentVerifierProvider contentVerifierProvider = new JcaContentVerifierProviderBuilder()
                .setProvider(new BouncyCastleProvider()).build(cert);
        DigestCalculatorProvider digestCalculatorProvider = new JcaDigestCalculatorProviderBuilder()
                .setProvider(new BouncyCastleProvider()).build();
        SignatureAlgorithmIdentifierFinder signatureAlgorithmIdentifierFinder = new DefaultSignatureAlgorithmIdentifierFinder();
        CMSSignatureAlgorithmNameGenerator signatureAlgorithmNameGenerator = new DefaultCMSSignatureAlgorithmNameGenerator();
        SignerInformationVerifier signerInformationVerifier = new SignerInformationVerifier(
                signatureAlgorithmNameGenerator, signatureAlgorithmIdentifierFinder, contentVerifierProvider,
                digestCalculatorProvider);

        return signerInformation.verify(signerInformationVerifier);

    } catch (LeafCertificateValidationException | IOException | CertificateException | OperatorCreationException
            | CMSException ex) {
        throw new SODException("No foi possivel verificar o SOD (" + ex.getMessage() + ")", ex);
    }
}

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   ww  w.ja va  2 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  w  w  .j a v  a2  s  . co  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.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;/* w  w  w  .ja v a2s.  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.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   www  .  j a v a 2 s  .  c  om
 *
 * @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;
    }
}