Entry

"In priority AX2012. Spread useful projects and materials for the development of business applications. Good luck!"

пятница, 27 декабря 2013 г.

Electronic signature and AX. Part 2: Create signature relying COM [AX2012]

Make simple electronic signature relying on COM object Cryptopro:
(Download object: http://www.cryptopro.ru/downloads)
str makeSignature(str   _dataForSign)
{
    COM             SignedData;
    COM             Signer;
    COM             SignerAuthenticatedAttributes;
    COM             oStore;
    COM             oStoreCertificates;
    COM             TimeAttribute;
    COM             oCertificates;
    COM             SelectedCertificate;
    COMVariant      oCertificate;
    COM             certificate;  
    str             sSignedMessage;
    str             ret;
    date            todayDate        = systemDateGet();
    utcDateTime     todayUTCDateTime = DateTimeUtil::getSystemDateTime();
    
    COM createObject(str _className)
    {
        COM COM;
        COM = new COM(_className);
        if (com != null)
        {
            return COM;
        }
        else
        {
            error("COM object is not initialized!");
            return null;
        }
    }

    //Init objects
    SignedData    = createObject("CAPICOM.SignedData");
    Signer        = createObject("CAPICOM.Signer");
    oStore        = createObject("CAPICOM.Store");
    TimeAttribute = createObject("CAPICOM.Attribute");

    //Find certificates
    try
    {
        //Open library
        oStore.Open(#CAPICOM_CURRENT_USER_STORE, #CAPICOM_MY_STORE, #CAPICOM_STORE_OPEN_READ_ONLY);
        oStoreCertificates = oStore.Certificates();
        //Filters
        oStoreCertificates = oStoreCertificates.Find(#CAPICOM_CERTIFICATE_FIND_KEY_USAGE, #CAPICOM_DIGITAL_SIGNATURE_KEY_USAGE);
        oStoreCertificates = oStoreCertificates.Find(#CAPICOM_CERTIFICATE_FIND_TIME_VALID);
        oStoreCertificates = oStoreCertificates.Find(#CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY, #CERT_KEY_SPEC_PROP_ID);
        oCertificates = oStoreCertificates;
    }
    catch(Exception::Error)
    {
        throw error("Find error!");
    }

    //If certificate selected
    if (oCertificates.Count() >= 1)
    {
        try
        {
            //Set signed data
            SignedData.Content(_dataForSign);
            //Open window to select certificate
            SelectedCertificate = oCertificates.Select();
            oCertificate = SelectedCertificate.Item(1);
            //Custom check to valid user serial num
            certificate = COM::createFromVariant(oCertificate);
            if(MyUserInfoTable::find(curUserId()).SerialNum != certificate.SerialNumber())
            {
                throw error("Check error");
            }
            //Configurate object
            Signer.Certificate(oCertificate);
            Signer.Options(1);
            //Create signature on BASE64 cod.
            sSignedMessage = SignedData.Sign(Signer, true, #CAPICOM_ENCODE_BASE64);
            ret = sSignedMessage;
        }
        catch(Exception::Error)
        {
            this.getErrorMessage("Create signature error!");
        }
    }
    else
    {
        this.getErrorMessage("Certificate not selected!");
    }

    //Cleare cashe
    TimeAttribute = null;
    Signer = null;
    oCertificate = null;
    SignedData = null;
    oCertificates = null;
    oStore.Close();
    oStore = null;

    return ret;
}