Example usage for org.bouncycastle.cms.jcajce JcaSimpleSignerInfoVerifierBuilder JcaSimpleSignerInfoVerifierBuilder

List of usage examples for org.bouncycastle.cms.jcajce JcaSimpleSignerInfoVerifierBuilder JcaSimpleSignerInfoVerifierBuilder

Introduction

In this page you can find the example usage for org.bouncycastle.cms.jcajce JcaSimpleSignerInfoVerifierBuilder JcaSimpleSignerInfoVerifierBuilder.

Prototype

JcaSimpleSignerInfoVerifierBuilder

Source Link

Usage

From source file:be.apsu.extremon.probes.tsp.TSPProbe.java

License:Open Source License

public TSPProbe() throws Exception {
    this.delay = confInt("delay", DEFAULT_DELAY);
    this.running = false;
    getAllowedSignatureOIDs(confStr(ALLOWED_SIGNATURE_CERTIFICATE_ALGORITHMS).split(","));

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

    url = new URL(confStr("url"));

    this.requestGenerator = new TimeStampRequestGenerator();
    this.requestGenerator.setCertReq(true);

    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    String encodedCert = confStr("tsa.certificate");
    X509Certificate tsaCert = (X509Certificate) certificateFactory
            .generateCertificate(new ByteArrayInputStream(Base64.decodeBase64(encodedCert)));
    JcaSimpleSignerInfoVerifierBuilder verifierBuilder = new JcaSimpleSignerInfoVerifierBuilder();
    this.signerVerifier = verifierBuilder.build(tsaCert);

    this.random = new Random();

    start();/*from ww w. j ava  2  s. co  m*/
    log("initialized");
}

From source file:be.e_contract.mycarenet.certra.CertRAClient.java

License:Open Source License

private byte[] getCmsData(byte[] cms) throws Exception {
    CMSSignedData cmsSignedData = new CMSSignedData(cms);
    SignerInformationStore signers = cmsSignedData.getSignerInfos();
    SignerInformation signer = (SignerInformation) signers.getSigners().iterator().next();
    SignerId signerId = signer.getSID();

    Store certificateStore = cmsSignedData.getCertificates();
    Collection<X509CertificateHolder> certificateCollection = certificateStore.getMatches(signerId);

    X509CertificateHolder certificateHolder = certificateCollection.iterator().next();
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    X509Certificate certificate = (X509Certificate) certificateFactory
            .generateCertificate(new ByteArrayInputStream(certificateHolder.getEncoded()));
    // we trust SSL here, no need for explicit verification of CMS signing
    // certificate

    LOG.debug("CMS signing certificate subject: " + certificate.getSubjectX500Principal());

    SignerInformationVerifier signerInformationVerifier = new JcaSimpleSignerInfoVerifierBuilder()
            .build(certificate);//  w w  w .ja  v  a2  s. co  m
    boolean signatureResult = signer.verify(signerInformationVerifier);
    if (false == signatureResult) {
        throw new SecurityException("woops");
    }

    CMSTypedData signedContent = cmsSignedData.getSignedContent();
    byte[] responseData = (byte[]) signedContent.getContent();

    return responseData;
}

From source file:be.e_contract.mycarenet.etee.EncryptionToken.java

License:Open Source License

private X509Certificate parseEncryptionCertificate(byte[] encodedEncryptionToken)
        throws CMSException, CertificateException, IOException, OperatorCreationException {
    CMSSignedData cmsSignedData = new CMSSignedData(encodedEncryptionToken);

    // get signer identifier
    SignerInformationStore signers = cmsSignedData.getSignerInfos();
    SignerInformation signer = (SignerInformation) signers.getSigners().iterator().next();
    SignerId signerId = signer.getSID();

    // get signer certificate
    Store certificateStore = cmsSignedData.getCertificates();
    LOG.debug("certificate store type: " + certificateStore.getClass().getName());
    @SuppressWarnings("unchecked")
    Collection<X509CertificateHolder> signingCertificateCollection = certificateStore.getMatches(signerId);
    X509CertificateHolder signingCertificateHolder = signingCertificateCollection.iterator().next();
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    X509Certificate signingCertificate = (X509Certificate) certificateFactory
            .generateCertificate(new ByteArrayInputStream(signingCertificateHolder.getEncoded()));
    LOG.debug("signing certificate: " + signingCertificate.getSubjectX500Principal());

    // verify CMS signature
    SignerInformationVerifier signerInformationVerifier = new JcaSimpleSignerInfoVerifierBuilder()
            .build(signingCertificate);//from  w  w w.  j a va 2  s .  c o m
    boolean signatureResult = signer.verify(signerInformationVerifier);
    if (false == signatureResult) {
        throw new SecurityException("ETK signature invalid");
    }

    // get encryption certificate
    CMSTypedData signedContent = cmsSignedData.getSignedContent();
    byte[] data = (byte[]) signedContent.getContent();
    X509Certificate encryptionCertificate = (X509Certificate) certificateFactory
            .generateCertificate(new ByteArrayInputStream(data));

    LOG.debug("all available certificates:");
    logCertificates(certificateStore, null);

    // get authentication certificate
    CustomSelector authenticationSelector = new CustomSelector();
    authenticationSelector.setSubject(encryptionCertificate.getIssuerX500Principal());
    @SuppressWarnings("unchecked")
    Collection<X509CertificateHolder> authenticationCertificates = certificateStore
            .getMatches(authenticationSelector);
    if (authenticationCertificates.size() != 1) {
        LOG.debug("no authentication certificate match");
    }
    X509CertificateHolder authenticationCertificateHolder = authenticationCertificates.iterator().next();
    this.authenticationCertificate = (X509Certificate) certificateFactory
            .generateCertificate(new ByteArrayInputStream(authenticationCertificateHolder.getEncoded()));

    verifyProxyCertificate(encryptionCertificate, this.authenticationCertificate);

    return encryptionCertificate;
}

From source file:be.e_contract.mycarenet.etee.Unsealer.java

License:Open Source License

private byte[] getVerifiedContent(byte[] cmsData)
        throws CertificateException, CMSException, IOException, OperatorCreationException {
    CMSSignedData cmsSignedData = new CMSSignedData(cmsData);
    SignerInformationStore signers = cmsSignedData.getSignerInfos();
    SignerInformation signer = (SignerInformation) signers.getSigners().iterator().next();
    SignerId signerId = signer.getSID();

    Store certificateStore = cmsSignedData.getCertificates();
    @SuppressWarnings("unchecked")
    Collection<X509CertificateHolder> certificateCollection = certificateStore.getMatches(signerId);
    if (null == this.senderCertificate) {
        if (certificateCollection.isEmpty()) {
            throw new SecurityException("no sender certificate present");
        }//from  w ww . j  ava  2 s  .  com
        X509CertificateHolder certificateHolder = certificateCollection.iterator().next();
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate) certificateFactory
                .generateCertificate(new ByteArrayInputStream(certificateHolder.getEncoded()));

        this.senderCertificate = certificate;
        LOG.debug("signer certificate subject: " + certificate.getSubjectX500Principal());
    }

    /*
     * By reusing the sender certificate we have the guarantee that the
     * outer signature and inner signature share the same origin.
     */
    SignerInformationVerifier signerInformationVerifier = new JcaSimpleSignerInfoVerifierBuilder()
            .build(this.senderCertificate);
    boolean signatureResult = signer.verify(signerInformationVerifier);
    if (false == signatureResult) {
        throw new SecurityException("woops");
    }

    CMSTypedData signedContent = cmsSignedData.getSignedContent();
    byte[] data = (byte[]) signedContent.getContent();
    return data;
}

From source file:br.gov.jfrj.siga.cd.AssinaturaDigital.java

License:Open Source License

@SuppressWarnings("unchecked")
protected static String validarAssinaturaCMS(byte[] digest, String digestAlgorithm, byte[] assinatura,
        Date dtAssinatura) throws InvalidKeyException, SecurityException, CRLException, CertificateException,
        NoSuchProviderException, NoSuchAlgorithmException, SignatureException, AplicacaoException,
        ChainValidationException, IOException, Exception {

    final CMSSignedData s;
    if (digest != null) {
        Map<String, byte[]> map = new HashMap<String, byte[]>();
        map.put(digestAlgorithm, digest);
        s = new CMSSignedData(map, assinatura);
    } else {//from w  w w  .  j ava  2s  .co  m
        s = new CMSSignedData(assinatura);
    }

    Store certs = s.getCertificates();
    SignerInformationStore signers = s.getSignerInfos();
    Collection<SignerInformation> c = signers.getSigners();
    Iterator<SignerInformation> it = c.iterator();
    X509CertificateHolder firstSignerCert = null;

    while (it.hasNext()) {
        SignerInformation signer = it.next();
        Collection<X509CertificateHolder> certCollection = certs.getMatches(signer.getSID());

        Iterator<X509CertificateHolder> certIt = certCollection.iterator();
        X509CertificateHolder cert = certIt.next();
        if (firstSignerCert == null)
            firstSignerCert = cert;

        if (!signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)))
            throw new Exception("Assinatura invlida!");

        System.out.println("\nSigner Info: \n");
        System.out.println("Is Signature Valid? true");
        System.out.println("Digest: " + asHex(signer.getContentDigest()));
        System.out.println("Enc Alg Oid: " + signer.getEncryptionAlgOID());
        System.out.println("Digest Alg Oid: " + signer.getDigestAlgOID());
        System.out.println("Signature: " + asHex(signer.getSignature()));

    }

    //      X509Certificate[] cadeiaTotal = montarCadeiaOrdenadaECompleta((Collection<X509Certificate>) (certs.getCertificates(null)));
    X509Certificate[] cadeiaTotal = montarCadeiaOrdenadaECompleta(certs.getMatches(null));

    List<X509CRLObject> crls = new ArrayList<>();
    if (certs.getMatches(null) != null) {
        Enumeration ec = ASN1Set.getInstance(certs.getMatches(null)).getObjects();

        while (ec.hasMoreElements()) {
            crls.add(new X509CRLObject(CertificateList.getInstance(ec.nextElement())));
        }
    }

    final X509ChainValidator cadeia = new X509ChainValidator(cadeiaTotal,
            /* trustedAnchors */new HashSet(FachadaDeCertificadosAC.getTrustAnchors()),
            crls.toArray(new X509CRLObject[0]));

    cadeia.checkCRL(true);

    try {
        cadeia.validateChain(dtAssinatura);
    } catch (Exception e1) {
        if (e1.getMessage().endsWith("Validation time is in future.")) {
            String s1 = e1.getMessage() + " Current date: [" + new Date().toString() + "]. Record date: ["
                    + dtAssinatura + "]. LCRs' dates [";
            for (X509CRLObject crl : (Collection<X509CRLObject>) certs.getMatches(null)) {
                String s2 = crl.getIssuerX500Principal().getName();
                s2 = s2.split(",")[0];

                s1 += s2 + " (" + crl.getThisUpdate() + " - " + crl.getNextUpdate() + ") ";
            }
            s1 += "]";
            throw new AplicacaoException(s1, 0, e1);
        } else
            throw e1;
    }

    //      String s1 = firstSignerCert.getSubjectDN().getName();
    String s1 = firstSignerCert.getSubject().toString();
    s1 = obterNomeExibicao(s1);

    return s1;
}

From source file:br.gov.jfrj.siga.cd.AssinaturaDigital.java

License:Open Source License

@SuppressWarnings("unchecked")
protected static String validarAssinaturaCMSeCarimboDeTempo(final byte[] digest, final String digestAlgorithm,
        final byte[] assinatura, Date dtAssinatura) throws InvalidKeyException, SecurityException, CRLException,
        CertificateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException,
        AplicacaoException, ChainValidationException, IOException, Exception {

    String nome = validarAssinaturaCMS(digest, digestAlgorithm, assinatura, dtAssinatura);

    Map<String, byte[]> map = new HashMap<String, byte[]>();
    map.put(digestAlgorithm, digest);//from  w  w w  .  j  av  a 2s .  c  o  m
    final CMSSignedData s = new CMSSignedData(map, assinatura);

    Collection ss = s.getSignerInfos().getSigners();
    SignerInformation si = (SignerInformation) ss.iterator().next();

    Attribute attr = si.getUnsignedAttributes().get(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken);
    CMSSignedData cmsTS = new CMSSignedData(attr.getAttrValues().getObjectAt(0).toASN1Primitive().getEncoded());

    TimeStampToken tok = new TimeStampToken(cmsTS);
    Store cs = tok.getCertificates();

    SignerId signer_id = tok.getSID();
    BigInteger cert_serial_number = signer_id.getSerialNumber();
    Collection certs = cs.getMatches(null);
    Iterator iter = certs.iterator();
    X509Certificate certificate = null;
    while (iter.hasNext()) {
        X509Certificate cert = (X509Certificate) iter.next();
        if (cert_serial_number != null) {
            if (cert.getSerialNumber().equals(cert_serial_number)) {
                certificate = cert;
            }
        } else {
            if (certificate == null) {
                certificate = cert;
            }
        }
    }

    tok.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(certificate));
    // Nato: falta validar as CRLs do carimbo de tempo

    if (!Arrays.equals(tok.getTimeStampInfo().getMessageImprintDigest(),
            MessageDigest.getInstance("SHA1").digest(si.getSignature()))) {
        throw new Exception("Carimbo de tempo no confere com o resumo do documento");
    }

    try {
        validarAssinaturaCMS(null, null, cmsTS.getEncoded(), tok.getTimeStampInfo().getGenTime());
    } catch (Exception e) {
        throw new Exception("Carimbo de tempo invlido!", e);
    }

    return nome;
}

From source file:br.gov.jfrj.siga.cd.AssinaturaDigital.java

License:Open Source License

@SuppressWarnings("unchecked")
public static String validarAssinaturaPKCS7(final byte[] digest, final String digestAlgorithm,
        final byte[] assinatura, Date dtAssinatura, boolean verificarLCRs)
        throws InvalidKeyException, SecurityException, CRLException, CertificateException,
        NoSuchProviderException, NoSuchAlgorithmException, SignatureException, AplicacaoException,
        ChainValidationException, IOException, Exception {

    Map<String, byte[]> map = new HashMap<String, byte[]>();
    map.put(digestAlgorithm, digest);/*from   ww w . j a v  a 2  s  .c om*/
    final CMSSignedData signedData = new CMSSignedData(map, assinatura);

    Store certs = signedData.getCertificates();
    SignerInformationStore signers = signedData.getSignerInfos();
    Collection<SignerInformation> c = signers.getSigners();
    Iterator<SignerInformation> it = c.iterator();

    String sCN = "";

    while (it.hasNext()) {
        SignerInformation signer = it.next();
        Collection<X509CertificateHolder> certCollection = certs.getMatches(signer.getSID());

        @SuppressWarnings("unused")
        String ss = signer.getDigestAlgOID();
        @SuppressWarnings("unused")
        String sss = signer.getDigestAlgorithmID().getObjectId().getId();

        Iterator<X509CertificateHolder> certIt = certCollection.iterator();
        X509CertificateHolder certHolder = certIt.next();
        X509Certificate cert = AssinaturaDigital.getX509Certificate(certHolder);

        if (!signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(certHolder)))
            throw new Exception("Assinatura invlida!");

        X509Certificate[] cadeiaTotal = montarCadeiaOrdenadaECompleta(certCollection);

        final X509ChainValidator cadeia = new X509ChainValidator(cadeiaTotal,
                /* trustedAnchors */new HashSet(FachadaDeCertificadosAC.getTrustAnchors()), null);
        cadeia.checkCRL(verificarLCRs);
        cadeia.validateChain(dtAssinatura);

        String s2 = cert.getSubjectDN().getName();
        s2 = obterNomeExibicao(s2);
        if (sCN.length() != 0)
            sCN += ", ";
        sCN += s2;
    }

    return sCN.length() == 0 ? null : sCN;
}

From source file:br.gov.jfrj.siga.cd.TimeStamper.java

License:Open Source License

private static TimeStampToken getTimeStampToken(byte[] content) throws Exception {
    TimeStampToken tsToken;//  www  .  j  a  v  a2  s. co  m

    boolean fSTF = true;

    if (!fSTF) {
        TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();

        reqGen.setCertReq(true);

        MessageDigest md = MessageDigest.getInstance("SHA1");

        md.update(content);

        byte[] assinatura = md.digest();

        TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, assinatura);

        // TimeStampRequestGenerator reqGen = new
        // TimeStampRequestGenerator();
        //
        // // request TSA to return certificate
        // reqGen.setCertReq(true);
        //
        // // Dummy request for sha1
        // // Sha256 "2.16.840.1.101.3.4.2.1", //
        // TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1,
        // MessageDigest.getInstance("SHA").digest(content));

        byte[] reqData = request.getEncoded();

        URL url;
        URLConnection urlConn;
        DataOutputStream printout;
        DataInputStream input;

        Properties systemProperties = System.getProperties();
        systemProperties.setProperty("http.proxyHost", SigaCdProperties.getProxyHost());
        systemProperties.setProperty("http.proxyPort", SigaCdProperties.getProxyPort());

        // URL of CGI-Bin script.
        //url = new URL("http://www.edelweb.fr/cgi-bin/service-tsp");
        url = new URL(SigaCdProperties.getTSPUrl());
        // url = new URL("http://www.cryptopro.ru/tsp/tsp.srf");
        // url = new URL("http://ns.szikszi.hu:8080/tsa");
        // url = new URL("http://time.certum.pl/");
        // URL connection channel.
        urlConn = url.openConnection();
        // Let the run-time system (RTS) know that we want input.
        urlConn.setDoInput(true);
        // Let the RTS know that we want to do output.
        urlConn.setDoOutput(true);
        // No caching, we want the real thing.
        urlConn.setUseCaches(false);
        // Specify the content type.
        urlConn.setRequestProperty("Content-Type", "application/timestamp-query");
        urlConn.setRequestProperty("Content-Length", String.valueOf(reqData.length));

        // Send POST output.
        printout = new DataOutputStream(urlConn.getOutputStream());
        printout.write(reqData);
        printout.flush();
        printout.close();
        // Get response data.
        input = new DataInputStream(urlConn.getInputStream());
        // byte[] ba = streamToByteArray(input);
        TimeStampResponse response = new TimeStampResponse(input);
        input.close();

        tsToken = response.getTimeStampToken();
    } else {

        tsToken = gerarCarimboTempo(content);
    }
    SignerId signer_id = tsToken.getSID();
    BigInteger cert_serial_number = signer_id.getSerialNumber();

    System.out.println("Signer ID serial " + signer_id.getSerialNumber());
    System.out.println("Signer ID issuer " + signer_id.getIssuer().toString());

    Store cs = tsToken.getCertificates();

    Collection certs = cs.getMatches(null);

    Iterator iter = certs.iterator();
    X509Certificate certificate = null;
    while (iter.hasNext()) {
        X509Certificate cert = (X509Certificate) iter.next();

        if (cert_serial_number != null) {
            if (cert.getSerialNumber().equals(cert_serial_number)) {
                System.out.println("using certificate with serial: " + cert.getSerialNumber());
                System.out.println(
                        "using certificate with base 64: " + Base64.encode(cert.getEncoded()) + "\n\n");

                certificate = cert;
            }
        } else {
            if (certificate == null) {
                certificate = cert;
            }
        }
        System.out.println("Certificate subject dn " + cert.getSubjectDN());
        System.out.println("Certificate serial " + cert.getSerialNumber());
    }

    // Nato: validao do carimbo de tempo est desabilitada porque existe
    // um problema no certificado do STF
    if (!fSTF)
        tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(certificate));

    System.out.println("TS info " + tsToken.getTimeStampInfo().getGenTime());
    System.out.println("TS info " + tsToken.getTimeStampInfo());
    System.out.println("TS info " + tsToken.getTimeStampInfo().getAccuracy());
    System.out.println("TS info " + tsToken.getTimeStampInfo().getNonce());
    return tsToken;
}

From source file:br.ufpb.dicomflow.integrationAPI.mail.impl.SMTPServiceExtractor.java

License:Open Source License

/**
  * verify the signature (assuming the cert is contained in the message)
  *///from  www.  j  a va  2s.  c  om
private boolean verify(SMIMESigned s) throws Exception {
    //
    // extract the information to verify the signatures.
    //

    //
    // certificates and crls passed in the signature - this must happen before
    // s.getSignerInfos()
    //
    Store certs = s.getCertificates();

    //
    // SignerInfo blocks which contain the signatures
    //
    SignerInformationStore signers = s.getSignerInfos();

    Collection c = signers.getSigners();
    Iterator it = c.iterator();

    //
    // check each signer
    //
    while (it.hasNext()) {
        SignerInformation signer = (SignerInformation) it.next();
        Collection certCollection = certs.getMatches(signer.getSID());

        Iterator certIt = certCollection.iterator();
        X509Certificate cert = new JcaX509CertificateConverter()
                .getCertificate((X509CertificateHolder) certIt.next());

        //
        // verify that the sign is correct and that it was generated
        // when the certificate was current
        //
        if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(cert))) {
            return true;
        } else {
            return false;
        }
    }
    return false;
}

From source file:ch.cyberduck.core.aquaticprime.ReceiptVerifier.java

License:Open Source License

@Override
public boolean verify() {
    try {/*from  w  ww .j  a  v  a2s .c  o  m*/
        // For additional security, you may verify the fingerprint of the root CA and the OIDs of the
        // intermediate CA and signing certificate. The OID in the Certificate Policies Extension of the
        // intermediate CA is (1 2 840 113635 100 5 6 1), and the Marker OID of the signing certificate
        // is (1 2 840 113635 100 6 11 1).
        final CMSSignedData s = new CMSSignedData(new FileInputStream(file.getAbsolute()));
        Store certs = s.getCertificates();
        SignerInformationStore signers = s.getSignerInfos();
        for (SignerInformation signer : (Iterable<SignerInformation>) signers.getSigners()) {
            final Collection<X509CertificateHolder> matches = certs.getMatches(signer.getSID());
            for (X509CertificateHolder holder : matches) {
                if (!signer.verify(new JcaSimpleSignerInfoVerifierBuilder()
                        .setProvider(new BouncyCastleProvider()).build(holder))) {
                    return false;
                }
            }
        }
        // Extract the receipt attributes
        final CMSProcessable signedContent = s.getSignedContent();
        byte[] originalContent = (byte[]) signedContent.getContent();
        final ASN1Primitive asn = ASN1Primitive.fromByteArray(originalContent);

        byte[] opaque = null;
        String bundleIdentifier = null;
        String bundleVersion = null;
        byte[] hash = null;

        if (asn instanceof ASN1Set) {
            // 2 Bundle identifier      Interpret as an ASN.1 UTF8STRING.
            // 3 Application version    Interpret as an ASN.1 UTF8STRING.
            // 4 Opaque value           Interpret as a series of bytes.
            // 5 SHA-1 hash             Interpret as a 20-byte SHA-1 digest value.
            final ASN1Set set = (ASN1Set) asn;
            final Enumeration enumeration = set.getObjects();
            while (enumeration.hasMoreElements()) {
                Object next = enumeration.nextElement();
                if (next instanceof DLSequence) {
                    DLSequence sequence = (DLSequence) next;
                    ASN1Encodable type = sequence.getObjectAt(0);
                    if (type instanceof ASN1Integer) {
                        if (((ASN1Integer) type).getValue().intValue() == 2) {
                            final ASN1Encodable value = sequence.getObjectAt(2);
                            if (value instanceof DEROctetString) {
                                bundleIdentifier = new String(((DEROctetString) value).getOctets(), "UTF-8");
                            }
                        } else if (((ASN1Integer) type).getValue().intValue() == 3) {
                            final ASN1Encodable value = sequence.getObjectAt(2);
                            if (value instanceof DEROctetString) {
                                bundleVersion = new String(((DEROctetString) value).getOctets(), "UTF-8");
                            }
                        } else if (((ASN1Integer) type).getValue().intValue() == 4) {
                            final ASN1Encodable value = sequence.getObjectAt(2);
                            if (value instanceof DEROctetString) {
                                opaque = ((DEROctetString) value).getOctets();
                            }
                        } else if (((ASN1Integer) type).getValue().intValue() == 5) {
                            final ASN1Encodable value = sequence.getObjectAt(2);
                            if (value instanceof DEROctetString) {
                                hash = ((DEROctetString) value).getOctets();
                            }
                        }
                    }
                }
            }
        } else {
            log.error(String.format("Expected set of attributes for %s", asn));
            return false;
        }
        if (!StringUtils.equals(PreferencesFactory.get().getDefault("application.identifier"),
                StringUtils.trim(bundleIdentifier))) {
            log.error(String.format("Bundle identifier %s in ASN set does not match", bundleIdentifier));
            return false;
        }
        if (!StringUtils.equals(PreferencesFactory.get().getDefault("application.version"),
                StringUtils.trim(bundleVersion))) {
            log.warn(String.format("Bundle version %s in ASN set does not match", bundleVersion));
        }
        final NetworkInterface en0 = NetworkInterface.getByName("en0");
        if (null == en0) {
            // Interface is not found when link is down #fail
            log.warn("No network interface en0");
            return true;
        } else {
            final byte[] mac = en0.getHardwareAddress();
            if (null == mac) {
                log.error("Cannot determine MAC address");
                // Continue without validation
                return true;
            }
            final String hex = Hex.encodeHexString(mac);
            if (log.isDebugEnabled()) {
                log.debug(String.format("Interface en0 %s", hex));
            }
            // Compute the hash of the GUID
            final MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(mac);
            if (null == opaque) {
                log.error(String.format("Missing opaque string in ASN.1 set %s", asn));
                return false;
            }
            digest.update(opaque);
            if (null == bundleIdentifier) {
                log.error(String.format("Missing bundle identifier in ASN.1 set %s", asn));
                return false;
            }
            digest.update(bundleIdentifier.getBytes(Charset.forName("UTF-8")));
            final byte[] result = digest.digest();
            if (Arrays.equals(result, hash)) {
                if (log.isInfoEnabled()) {
                    log.info(String.format("Valid receipt for GUID %s", hex));
                }
                guid = hex;
                return true;
            } else {
                log.error(String.format("Failed verification. Hash with GUID %s does not match hash in receipt",
                        hex));
                return false;
            }
        }
    } catch (IOException e) {
        log.error("Receipt validation error", e);
        // Shutdown if receipt is not valid
        return false;
    } catch (GeneralSecurityException e) {
        log.error("Receipt validation error", e);
        // Shutdown if receipt is not valid
        return false;
    } catch (SecurityException e) {
        log.error("Receipt validation error", e);
        // Shutdown if receipt is not valid
        return false;
    } catch (CMSException e) {
        log.error("Receipt validation error", e);
        // Shutdown if receipt is not valid
        return false;
    } catch (Exception e) {
        log.error("Unknown receipt validation error", e);
        return true;
    }
}