package kz.gamma;

import kz.gamma.asn1.x509.X509Name;
import kz.gamma.cms.CMSProcessableByteArray;
import kz.gamma.cms.CMSSignedData;
import kz.gamma.cms.CMSSignedDataGenerator;
import kz.gamma.jce.provider.GammaTechProvider;
import kz.gamma.tumarcsp.params.StoreObjectParam;
import kz.gamma.util.encoders.Base64;

import java.io.ByteArrayInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

/**
 * Created by a_mukusheva on 12.02.2016.
 */
public class CMSCreation {
    /**
     * Формирование cms
     *
     * @param dataToSign - данные для подписи
     * @param profile    - имя профиля, используемого для подписи
     * @param password   - пароль к профилю
     * @param DN         - dn сертификата, который используется для подписи
     * @return
     */
    public byte[] createCMS(byte[] dataToSign, String profile, String password, String DN) {
        CMSSignedData signedData = null;
        byte[] signedDataBytes = null;
        try {
            //Загружаем профиль
            KeyStore keyStore = KeyStore.getInstance("GKS", GammaTechProvider.PROVIDER_NAME);
            keyStore.load(new ByteArrayInputStream(profile.getBytes()), password.toCharArray());
            //Получаем закрытый ключ и сертификат
            Enumeration en = keyStore.aliases();
            String alias = null;
            while (en.hasMoreElements()) {
                StoreObjectParam profParam = (StoreObjectParam) en.nextElement();
                if ((new X509Name(DN)).equals(new X509Name(profParam.getDn()))) {
                    alias = profParam.getSn();
                }
            }
            PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, null);
            X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias);

            //Формируем CMS
            CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
            gen.addSigner(privateKey, certificate, CMSSignedDataGenerator.DIGEST_GOST3411G);
            CMSProcessableByteArray content = new CMSProcessableByteArray(dataToSign);
            signedData = gen.generate(content, false, GammaTechProvider.PROVIDER_NAME);
            signedDataBytes = signedData.getEncoded();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return signedDataBytes;
    }

    public static void main(String[] args) {
        if (args.length != 4) {
            System.out.println("Usage:\n" +
                    "Данные для подписи\t" + "Имя профиля\t" + "Пароль к профилю\t" + "DN\n");
            return;
        }
        byte[] dataToSign = args[0].getBytes();
        String profileName = args[1];
        String profilePassword = args[2];
        String DN = args[3];//например "cn=usernika,o=gamma,c=KZ"

        Security.addProvider(new GammaTechProvider());
        CMSCreation cmsCreation = new CMSCreation();
        byte[] cms = cmsCreation.createCMS(dataToSign, profileName, profilePassword, DN);
        System.out.println("CMS: " + new String(Base64.encode(cms)));
    }
}
