node_modules/pkijs/org/pkijs/cms_simpl.js
// #region Special sub-functions to work with each recipient's type 
region Special sub-functions to work with each recipient's type
region Special sub - functions to work with each recipient ' s type
function KeyAgreeRecipientInfo(index)
        {
            var currentSequence = Promise.resolve();
            var recipientCurve;
            var recipientCurveLength;
            var curveOID;
            var ecdhPrivateKey;
            currentSequence = currentSequence.then(
                function(result)
                {
                    if(("recipientCertificate" in decryptionParameters) === false)
                        return Promise.reject("Parameter \"recipientCertificate\" is mandatory for \"KeyAgreeRecipientInfo\"");
                    if(("recipientPrivateKey" in decryptionParameters) === false)
                        return Promise.reject("Parameter \"recipientPrivateKey\" is mandatory for \"KeyAgreeRecipientInfo\"");
                    var curveObject = decryptionParameters.recipientCertificate.subjectPublicKeyInfo.algorithm.algorithm_params;
                    if((curveObject instanceof in_window.org.pkijs.asn1.OID) === false)
                        return Promise.reject("Incorrect \"recipientCertificate\" for index " + index);
                    curveOID = curveObject.value_block.toString();
                    switch(curveOID)
                    {
                        case "1.2.840.10045.3.1.7":
                            recipientCurve = "P-256";
                            recipientCurveLength = 256;
                            break;
                        case "1.3.132.0.34":
                            recipientCurve = "P-384";
                            recipientCurveLength = 384;
                            break;
                        case "1.3.132.0.35":
                            recipientCurve = "P-521";
                            recipientCurveLength = 528;
                            break;
                        default:
                            return Promise.reject("Incorrect curve OID for index " + index);
                    }
                    return crypto.importKey("pkcs8",
                        decryptionParameters.recipientPrivateKey,
                        {
                            name: "ECDH",
                            namedCurve: recipientCurve
                        },
                        true,
                        ["deriveBits"]
                        );
                },
                function(error)
                {
                    return Promise.reject(error);
                }
                );
            currentSequence = currentSequence.then(
                function(result)
                {
                    ecdhPrivateKey = result;
                    if(("algorithm_params" in _this.recipientInfos[index].value.originator.value.algorithm) === false)
                        _this.recipientInfos[index].value.originator.value.algorithm.algorithm_params = new in_window.org.pkijs.asn1.OID({ value: curveOID });
                    var buffer = _this.recipientInfos[index].value.originator.value.toSchema().toBER(false);
                    return crypto.importKey("spki", 
                        buffer,
                        {
                            name: "ECDH",
                            namedCurve: recipientCurve
                        },
                        true,
                        []);
                },
                function(error)
                {
                    return Promise.reject(error);
                }
                );
            currentSequence = currentSequence.then(
                function(result)
                {
                    return crypto.deriveBits({
                        name: "ECDH",
                        public: result
                    },
                    ecdhPrivateKey,
                    recipientCurveLength);
                },
                function(error)
                {
                    return Promise.reject(error);
                }
                );
            currentSequence = currentSequence.then(
                function(result)
                {
                    var aesKWAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: _this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithm_params });
                    var KWalgorithm = in_window.org.pkijs.getAlgorithmByOID(aesKWAlgorithm.algorithm_id);
                    if(("name" in KWalgorithm) === false)
                        return Promise.reject("Incorrect OID for key encryption algorithm: " + aesKWAlgorithm.algorithm_id);
                    var kwLength = KWalgorithm.length;
                    var kwLengthBuffer = new ArrayBuffer(4);
                    var kwLengthView = new Uint8Array(kwLengthBuffer);
                    for(var j = 3; j >= 0; j--)
                    {
                        kwLengthView[j] = kwLength;
                        kwLength >>= 8;
                    }
                    var eccInfo = new in_window.org.pkijs.simpl.cms.ECC_CMS_SharedInfo({
                        keyInfo: new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({
                            algorithm_id: aesKWAlgorithm.algorithm_id,
                            algorithm_params: new in_window.org.pkijs.asn1.NULL()
                        }),
                        entityUInfo: _this.recipientInfos[index].value.ukm,
                        suppPubInfo: new in_window.org.pkijs.asn1.OCTETSTRING({ value_hex: kwLengthBuffer })
                    });
                    var encodedInfo = eccInfo.toSchema().toBER(false);
                    var ecdhAlgorithm = in_window.org.pkijs.getAlgorithmByOID(_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithm_id);
                    if(("name" in ecdhAlgorithm) === false)
                        return Promise.reject("Incorrect OID for key encryption algorithm: " + _this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithm_id);
                    return in_window.org.pkijs.simpl.cms.kdf(ecdhAlgorithm.kdf, result, KWalgorithm.length, encodedInfo);
                },
                function(error)
                {
                    return Promise.reject(error);
                }
                );
            currentSequence = currentSequence.then(
                function(result)
                {
                    return crypto.importKey("raw",
                        result,
                        { name: "AES-KW" },
                        true,
                        ["unwrapKey"]);
                },
                function(error)
                {
                    return Promise.reject(error);
                }
                );
            currentSequence = currentSequence.then(
                function(result)
                {
                    var contentEncryptionAlgorithm = in_window.org.pkijs.getAlgorithmByOID(_this.encryptedContentInfo.contentEncryptionAlgorithm.algorithm_id);
                    if(("name" in contentEncryptionAlgorithm) === false)
                        return Promise.reject("Incorrect \"contentEncryptionAlgorithm\": " + _this.encryptedContentInfo.contentEncryptionAlgorithm.algorithm_id);
                    return crypto.unwrapKey("raw",
                        _this.recipientInfos[index].value.recipientEncryptedKeys.encryptedKeys[0].encryptedKey.value_block.value_hex,
                        result,
                        { name: "AES-KW" },
                        contentEncryptionAlgorithm,
                        true,
                        ["decrypt"]);
                },
                function(error)
                {
                    return Promise.reject(error);
                }
                );
            return currentSequence;
        }
function KeyAgreeRecipientInfo ( index ) { var currentSequence = Promise . resolve ( ) ; var recipientCurve ; var recipientCurveLength ; var curveOID ; var ecdhPrivateKey ; currentSequence = currentSequence . then ( function ( result ) { if ( ( "recipientCertificate" in decryptionParameters ) === false ) return Promise . reject ( "Parameter \"recipientCertificate\" is mandatory for \"KeyAgreeRecipientInfo\"" ) ; if ( ( "recipientPrivateKey" in decryptionParameters ) === false ) return Promise . reject ( "Parameter \"recipientPrivateKey\" is mandatory for \"KeyAgreeRecipientInfo\"" ) ; var curveObject = decryptionParameters . recipientCertificate . subjectPublicKeyInfo . algorithm . algorithm_params ; if ( ( curveObject instanceof in_window . org . pkijs . asn1 . OID ) === false ) return Promise . reject ( "Incorrect \"recipientCertificate\" for index " + index ) ; curveOID = curveObject . value_block . toString ( ) ; switch ( curveOID ) { case "1.2.840.10045.3.1.7" : recipientCurve = "P-256" ; recipientCurveLength = 256 ; break ; case "1.3.132.0.34" : recipientCurve = "P-384" ; recipientCurveLength = 384 ; break ; case "1.3.132.0.35" : recipientCurve = "P-521" ; recipientCurveLength = 528 ; break ; default : return Promise . reject ( "Incorrect curve OID for index " + index ) ; } return crypto . importKey ( "pkcs8" , decryptionParameters . recipientPrivateKey , { name : "ECDH" , namedCurve : recipientCurve } , true , [ "deriveBits" ] ) ; } , function ( error ) { return Promise . reject ( error ) ; } ) ; currentSequence = currentSequence . then ( function ( result ) { ecdhPrivateKey = result ; if ( ( "algorithm_params" in _this . recipientInfos [ index ] . value . originator . value . algorithm ) === false ) _this . recipientInfos [ index ] . value . originator . value . algorithm . algorithm_params = new in_window . org . pkijs . asn1 . OID ( { value : curveOID } ) ; var buffer = _this . recipientInfos [ index ] . value . originator . value . toSchema ( ) . toBER ( false ) ; return crypto . importKey ( "spki" , buffer , { name : "ECDH" , namedCurve : recipientCurve } , true , [ ] ) ; } , function ( error ) { return Promise . reject ( error ) ; } ) ; currentSequence = currentSequence . then ( function ( result ) { return crypto . deriveBits ( { name : "ECDH" , public : result } , ecdhPrivateKey , recipientCurveLength ) ; } , function ( error ) { return Promise . reject ( error ) ; } ) ; currentSequence = currentSequence . then ( function ( result ) { var aesKWAlgorithm = new in_window . org . pkijs . simpl . ALGORITHM_IDENTIFIER ( { schema : _this . recipientInfos [ index ] . value . keyEncryptionAlgorithm . algorithm_params } ) ; var KWalgorithm = in_window . org . pkijs . getAlgorithmByOID ( aesKWAlgorithm . algorithm_id ) ; if ( ( "name" in KWalgorithm ) === false ) return Promise . reject ( "Incorrect OID for key encryption algorithm: " + aesKWAlgorithm . algorithm_id ) ; var kwLength = KWalgorithm . length ; var kwLengthBuffer = new ArrayBuffer ( 4 ) ; var kwLengthView = new Uint8Array ( kwLengthBuffer ) ; for ( var j = 3 ; j >= 0 ; j -- ) { kwLengthView [ j ] = kwLength ; kwLength >>= 8 ; } var eccInfo = new in_window . org . pkijs . simpl . cms . ECC_CMS_SharedInfo ( { keyInfo : new in_window . org . pkijs . simpl . ALGORITHM_IDENTIFIER ( { algorithm_id : aesKWAlgorithm . algorithm_id , algorithm_params : new in_window . org . pkijs . asn1 . NULL ( ) } ) , entityUInfo : _this . recipientInfos [ index ] . value . ukm , suppPubInfo : new in_window . org . pkijs . asn1 . OCTETSTRING ( { value_hex : kwLengthBuffer } ) } ) ; var encodedInfo = eccInfo . toSchema ( ) . toBER ( false ) ; var ecdhAlgorithm = in_window . org . pkijs . getAlgorithmByOID ( _this . recipientInfos [ index ] . value . keyEncryptionAlgorithm . algorithm_id ) ; if ( ( "name" in ecdhAlgorithm ) === false ) return Promise . reject ( "Incorrect OID for key encryption algorithm: " + _this . recipientInfos [ index ] . value . keyEncryptionAlgorithm . algorithm_id ) ; return in_window . org . pkijs . simpl . cms . kdf ( ecdhAlgorithm . kdf , result , KWalgorithm . length , encodedInfo ) ; } , function ( error ) { return Promise . reject ( error ) ; } ) ; currentSequence = currentSequence . then ( function ( result ) { return crypto . importKey ( "raw" , result , { name : "AES-KW" } , true , [ "unwrapKey" ] ) ; } , function ( error ) { return Promise . reject ( error ) ; } ) ; currentSequence = currentSequence . then ( function ( result ) { var contentEncryptionAlgorithm = in_window . org . pkijs . getAlgorithmByOID ( _this . encryptedContentInfo . contentEncryptionAlgorithm . algorithm_id ) ; if ( ( "name" in contentEncryptionAlgorithm ) === false ) return Promise . reject ( "Incorrect \"contentEncryptionAlgorithm\": " + _this . encryptedContentInfo . contentEncryptionAlgorithm . algorithm_id ) ; return crypto . unwrapKey ( "raw" , _this . recipientInfos [ index ] . value . recipientEncryptedKeys . encryptedKeys [ 0 ] . encryptedKey . value_block . value_hex , result , { name : "AES-KW" } , contentEncryptionAlgorithm , true , [ "decrypt" ] ) ; } , function ( error ) { return Promise . reject ( error ) ; } ) ; return currentSequence ; }
region Special sub-functions to work with each recipient's type
region Special sub - functions to work with each recipient ' s type
// #region Initial variables  // #endregion  // #region Get "namedCurve" parameter from recipient's certificate  // #endregion  // #region Import sender's ephemeral public key  // #region Change "OriginatorPublicKey" if "curve" parameter absent // #endregion  // #region Create ArrayBuffer with sender's public key  // #endregion  // #endregion  // #region Create shared secret  // #endregion  // #region Apply KDF function to shared secret  // #region Get length of used AES-KW algorithm  // #endregion  // #region Translate AES-KW length to ArrayBuffer  // #endregion  // #region Create and encode "ECC-CMS-SharedInfo" structure  /*
                             Initially RFC5753 says that AES algorithms have absent parameters.
                             But since early implementations all put NULL here. Thus, in order to be
                             "backward compatible", index also put NULL here.
                            */ // #endregion  // #region Get SHA algorithm used together with ECDH  // #endregion  // #endregion  // #region Import AES-KW key from result of KDF function  // #endregion  // #region Finally unwrap session key  // #region Get WebCrypto form of content encryption algorithm  // #endregion  // #endregion 