ru.codeinside.gws.crypto.cryptopro.SunPkcs7.java Source code

Java tutorial

Introduction

Here is the source code for ru.codeinside.gws.crypto.cryptopro.SunPkcs7.java

Source

/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * Copyright (c) 2013, MPL CodeInside http://codeinside.ru
 */

package ru.codeinside.gws.crypto.cryptopro;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import ru.codeinside.gws.api.Signature;
import sun.security.pkcs.ContentInfo;
import sun.security.pkcs.PKCS7;
import sun.security.pkcs.ParsingException;
import sun.security.pkcs.SignerInfo;
import sun.security.util.DerOutputStream;
import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.cert.X509Certificate;

final public class SunPkcs7 {

    final static ObjectIdentifier GOST3410;
    final static ObjectIdentifier GOST3411;

    static {
        try {
            GOST3410 = new ObjectIdentifier("1.2.643.2.2.19");
            GOST3411 = new ObjectIdentifier("1.2.643.2.2.9");
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

    final private static Log log = LogFactory.getLog(CryptoProvider.class);

    public static byte[] toPkcs7(final Signature signature) {
        final X509Certificate certificate = signature.certificate;
        final byte[] sign = signature.sign;
        X500Name issuer = X500Name.asX500Name(certificate.getIssuerX500Principal());
        final AlgorithmId digestAlgorithmId = new AlgorithmId(GOST3411);
        final AlgorithmId signAlgorithmId = new AlgorithmId(GOST3410);
        SignerInfo sInfo = new SignerInfo(issuer, certificate.getSerialNumber(), digestAlgorithmId, signAlgorithmId,
                sign);
        ContentInfo cInfo = new ContentInfo(ContentInfo.DATA_OID, null);
        PKCS7 pkcs7 = new PKCS7(new AlgorithmId[] { digestAlgorithmId }, cInfo,
                new X509Certificate[] { certificate }, new SignerInfo[] { sInfo });
        final ByteArrayOutputStream bOut = new DerOutputStream();
        try {
            pkcs7.encodeSignedData(bOut);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return bOut.toByteArray();
    }

    public static Signature fromPkcs7(final byte[] bytes) {
        final PKCS7 pkcs7;
        try {
            pkcs7 = new PKCS7(bytes);
        } catch (ParsingException e) {
            log.info("fail parse pkcs7: ", e);
            return new Signature(null, null, null, false);
        }

        final AlgorithmId digestAlgorithmId = new AlgorithmId(GOST3411);
        final AlgorithmId signAlgorithmId = new AlgorithmId(GOST3410);
        final AlgorithmId[] digestAlgorithmIds = pkcs7.getDigestAlgorithmIds();

        if (digestAlgorithmIds == null || digestAlgorithmIds.length == 0) {
            log.info("no digestAlgorithm in pkcs7");
        } else if (!digestAlgorithmIds[0].equals(digestAlgorithmId)) {
            log.info("no GOST3411 in pkcs7");
        } else {
            final X509Certificate[] certificates = pkcs7.getCertificates();
            if (certificates == null || certificates.length == 0) {
                log.info("no certificate in pkcs7");
            } else {
                final X509Certificate certificate = certificates[0];
                final SignerInfo[] signerInfos = pkcs7.getSignerInfos();
                if (signerInfos == null || signerInfos.length == 0) {
                    log.info("no signerInfos in pkcs7");
                } else {
                    final SignerInfo signerInfo = signerInfos[0];
                    if (!signerInfo.getIssuerName()
                            .equals(X500Name.asX500Name(certificate.getIssuerX500Principal()))) {
                        log.info("invalid issuerX500Principal in pkcs7");
                    } else if (!signerInfo.getDigestAlgorithmId().equals(digestAlgorithmId)) {
                        log.info("no GOST3411 in pkcs7");
                    } else if (!signerInfo.getDigestEncryptionAlgorithmId().equals(signAlgorithmId)) {
                        log.info("no GOST3410 in pkcs7");
                    } else if (!signerInfo.getCertificateSerialNumber().equals(certificate.getSerialNumber())) {
                        log.info("invalid certificate serial number in pkcs7");
                    } else {
                        return new Signature(certificate, null, signerInfo.getEncryptedDigest(), true);
                    }
                }
            }
        }
        return new Signature(null, null, null, false);
    }

}