예제 #1
0
        internal int AddObject(CryptokiObjectType type, object data)
        {
            int handle = Interlocked.Increment(ref s_nextHandle);

            m_objects[handle] = new CryptokiObject(type, data);

            return(handle);
        }
예제 #2
0
        public bool FindObjects(int session, IntPtr phObjects, int ulMaxCount, out int pulObjectCount)
        {
            pulObjectCount = 0;

            try
            {
                SessionData        ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);
                FindObjectsContext foc = ctx.FindObjCtx;

                if (foc == null)
                {
                    return(false);
                }

                int[] handles = new int[ctx.ObjectCtx.m_objects.Count];
                int   idx     = 0;

                Dictionary <int, CryptokiObject> .Enumerator enm = ctx.ObjectCtx.m_objects.GetEnumerator();

                while (enm.MoveNext())
                {
                    CryptokiObject obj = enm.Current.Value;
                    if (foc.Type == obj.Type)
                    {
                        if ((string)obj.Properties["Group"] == foc.Group)
                        {
                            if ((string)obj.Properties["FileName"] == foc.FileName || foc.FileName == "")
                            {
                                handles[idx++] = enm.Current.Key;
                            }
                        }
                    }
                }

                if (idx == 0 && foc.FileName == "NetMF_DeviceKey")
                {
                    handles[idx++] = ctx.ObjectCtx.AddObject(CryptokiObjectType.Key, m_deviceKey);
                }

                pulObjectCount = idx;

                if (idx > 0 && phObjects != IntPtr.Zero)
                {
                    Marshal.Copy(handles, 0, phObjects, idx);
                }

                return(true);
            }
            catch
            {
                return(false);
            }
        }
예제 #3
0
        private bool Init(int session, AlgorithmType alg, AlgorithmType hash, int hKey, bool isVerify)
        {
            //bool bRet = false;
            try
            {
                SessionData ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);

                KeyData        kd  = null;
                CryptokiObject obj = ctx.ObjectCtx.GetObject(hKey);

                if (obj == null)
                {
                    return(false);
                }

                if (obj.Type == CryptokiObjectType.Key)
                {
                    kd = obj.Data as KeyData;
                }
                else if (obj.Type == CryptokiObjectType.Cert)
                {
                    X509Certificate2 cert = obj.Data as X509Certificate2;

                    kd = new KeyData(null, cert);
                }
                else
                {
                    return(false);
                }

                byte[] keyData = kd.KeyBytes;

                // remove
                if (((uint)((uint)hash & (uint)CryptokiObjectMgrDriver.CryptokiAttribType.SIGN_NO_NODIGEST_FLAG)) != 0)
                {
                    m_signHash = true;
                    hash       = (AlgorithmType)((uint)hash & ~(uint)CryptokiObjectMgrDriver.CryptokiAttribType.SIGN_NO_NODIGEST_FLAG);
                }
                else
                {
                    m_signHash = false;
                }

                switch (alg)
                {
                case AlgorithmType.RSA_PKCS:
                {
                    RSACryptoServiceProvider csp;
                    SignatureData            sigData = isVerify ? ctx.VerifyCtx : ctx.SignCtx;

                    if (keyData != null)
                    {
                        csp = new RSACryptoServiceProvider();
                        csp.ImportCspBlob(keyData);
                    }
                    else
                    {
                        X509Certificate2 cert = kd.KeyCsp as X509Certificate2;

                        if (isVerify)
                        {
                            csp = cert.PublicKey.Key as RSACryptoServiceProvider;
                        }
                        else
                        {
                            csp = cert.PrivateKey as RSACryptoServiceProvider;
                        }
                    }

                    if (isVerify)
                    {
                        sigData.SignObject = new RSAPKCS1SignatureDeformatter(csp);
                    }
                    else
                    {
                        sigData.SignObject = new RSAPKCS1SignatureFormatter(csp);
                    }

                    switch (hash)
                    {
                    case AlgorithmType.SHA_1:
                        sigData.SignHashAlg = new SHA1CryptoServiceProvider();
                        if (isVerify)
                        {
                            ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA1");
                        }
                        else
                        {
                            ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA1");
                        }
                        break;

                    case AlgorithmType.SHA256:
                        sigData.SignHashAlg = new SHA256CryptoServiceProvider();
                        if (isVerify)
                        {
                            ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA256");
                        }
                        else
                        {
                            ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA256");
                        }
                        break;

                    case AlgorithmType.SHA512:
                        sigData.SignHashAlg = new SHA512CryptoServiceProvider();
                        if (isVerify)
                        {
                            ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA512");
                        }
                        else
                        {
                            ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA512");
                        }
                        break;

                    case AlgorithmType.MD5:
                        sigData.SignHashAlg = new MD5CryptoServiceProvider();
                        if (isVerify)
                        {
                            ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("MD5");
                        }
                        else
                        {
                            ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("MD5");
                        }
                        break;

                    // no hash, means that we are signing a hash value
                    case (AlgorithmType)(uint.MaxValue):
                        break;

                    default:
                        return(false);
                    }
                }
                break;

                case AlgorithmType.ECDSA:
                {
                    ECDsaCng csp = kd.KeyCsp as ECDsaCng;

                    if (csp == null)
                    {
                        return(false);
                    }

                    SignatureData sigData = isVerify ? ctx.VerifyCtx : ctx.SignCtx;

                    sigData.SignObject = csp;

                    switch (hash)
                    {
                    case AlgorithmType.SHA_1:
                        csp.HashAlgorithm   = CngAlgorithm.Sha1;
                        sigData.SignHashAlg = new SHA1CryptoServiceProvider();
                        break;

                    case AlgorithmType.SHA256:
                        csp.HashAlgorithm   = CngAlgorithm.Sha256;
                        sigData.SignHashAlg = new SHA256CryptoServiceProvider();
                        break;

                    case AlgorithmType.SHA384:
                        csp.HashAlgorithm   = CngAlgorithm.Sha384;
                        sigData.SignHashAlg = new SHA384CryptoServiceProvider();
                        break;

                    case AlgorithmType.SHA512:
                        csp.HashAlgorithm   = CngAlgorithm.Sha512;
                        sigData.SignHashAlg = new SHA512CryptoServiceProvider();
                        break;

                    case AlgorithmType.MD5:
                        csp.HashAlgorithm   = CngAlgorithm.MD5;
                        sigData.SignHashAlg = new MD5CryptoServiceProvider();
                        break;

                    default:
                        return(false);
                    }
                }
                break;

                case AlgorithmType.DSA:
                {
                    DSACryptoServiceProvider csp = new DSACryptoServiceProvider();

                    csp.ImportCspBlob(keyData);

                    SignatureData sigData = isVerify ? ctx.VerifyCtx : ctx.SignCtx;

                    if (isVerify)
                    {
                        sigData.SignObject = new DSASignatureDeformatter(csp);
                    }
                    else
                    {
                        sigData.SignObject = new DSASignatureFormatter(csp);
                    }

                    switch (hash)
                    {
                    case AlgorithmType.SHA_1:
                        sigData.SignHashAlg = new SHA1CryptoServiceProvider();
                        if (isVerify)
                        {
                            ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA1");
                        }
                        else
                        {
                            ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA1");
                        }
                        break;

                    case AlgorithmType.SHA256:
                        sigData.SignHashAlg = new SHA256CryptoServiceProvider();
                        if (isVerify)
                        {
                            ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA256");
                        }
                        else
                        {
                            ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA256");
                        }
                        break;

                    case AlgorithmType.SHA512:
                        sigData.SignHashAlg = new SHA512CryptoServiceProvider();
                        if (isVerify)
                        {
                            ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA512");
                        }
                        else
                        {
                            ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA512");
                        }
                        break;

                    case AlgorithmType.MD5:
                        sigData.SignHashAlg = new MD5CryptoServiceProvider();
                        if (isVerify)
                        {
                            ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("MD5");
                        }
                        else
                        {
                            ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("MD5");
                        }
                        break;

                    default:
                        return(false);
                    }
                }
                break;

                default:
                    return(false);
                }
            }
            catch (Exception e)
            {
                Debug.Print("Exception: " + e.Message);
                return(false);
            }

            return(true);
        }
예제 #4
0
        bool IEncryptionDriver.EncryptInit(int session, int alg, IntPtr algParam, int algParamLen, int hKey)
        {
            try
            {
                SessionData ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);

                KeyData        kd  = null;
                CryptokiObject obj = ctx.ObjectCtx.GetObject(hKey);

                if (obj == null)
                {
                    return(false);
                }

                if (obj.Type == CryptokiObjectType.Key)
                {
                    kd = obj.Data as KeyData;
                }
                else if (obj.Type == CryptokiObjectType.Cert)
                {
                    X509Certificate2 cert = obj.Data as X509Certificate2;

                    AsymmetricAlgorithm encAlg = cert.PublicKey.Key;

                    kd = new KeyData(null, encAlg);
                }
                else
                {
                    return(false);
                }

                byte[] keyData = kd.KeyBytes;
                byte[] IV      = null;

                if (algParam != IntPtr.Zero)
                {
                    IV = new byte[algParamLen];

                    Marshal.Copy(algParam, IV, 0, algParamLen);
                }

                ctx.EncryptCtx.CryptoAlgorithm = (AlgorithmType)alg;

                switch ((AlgorithmType)alg)
                {
                case AlgorithmType.DES3_CBC_PAD:
                {
                    TripleDESCryptoServiceProvider des3 = new TripleDESCryptoServiceProvider();
                    des3.Padding = PaddingMode.PKCS7;
                    ctx.EncryptCtx.CryptoObject    = des3;
                    ctx.EncryptCtx.CryptoTransform = des3.CreateEncryptor(keyData, IV);
                }
                break;

                case AlgorithmType.DES3_CBC:
                {
                    TripleDESCryptoServiceProvider des3 = new TripleDESCryptoServiceProvider();
                    des3.Padding = PaddingMode.None;
                    ctx.EncryptCtx.CryptoObject    = des3;
                    ctx.EncryptCtx.CryptoTransform = des3.CreateEncryptor(keyData, IV);
                }
                break;

                case AlgorithmType.AES_CBC_PAD:
                {
                    AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
                    aes.Padding = PaddingMode.PKCS7;
                    aes.Mode    = CipherMode.CBC;
                    ctx.EncryptCtx.CryptoObject    = aes;
                    ctx.EncryptCtx.CryptoTransform = aes.CreateEncryptor(keyData, IV);
                }
                break;

                case AlgorithmType.AES_ECB_PAD:
                {
                    AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
                    aes.Padding = PaddingMode.PKCS7;
                    aes.Mode    = CipherMode.ECB;
                    ctx.EncryptCtx.CryptoObject    = aes;
                    ctx.EncryptCtx.CryptoTransform = aes.CreateEncryptor(keyData, IV);
                }
                break;

                case AlgorithmType.AES_CBC:
                {
                    AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
                    aes.Padding = PaddingMode.None;
                    aes.Mode    = CipherMode.CBC;
                    ctx.EncryptCtx.CryptoObject    = aes;
                    ctx.EncryptCtx.CryptoTransform = aes.CreateEncryptor(keyData, IV);
                }
                break;

                case AlgorithmType.AES_ECB:
                {
                    AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
                    aes.Padding = PaddingMode.None;
                    aes.Mode    = CipherMode.ECB;
                    ctx.EncryptCtx.CryptoObject    = aes;
                    ctx.EncryptCtx.CryptoTransform = aes.CreateEncryptor(keyData, IV);
                }
                break;

                case AlgorithmType.RSA_PKCS:
                    if (keyData == null)
                    {
                        ctx.EncryptCtx.CryptoObject = kd.KeyCsp as IDisposable;
                    }
                    else
                    {
                        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                        ctx.EncryptCtx.CryptoObject = rsa;
                        rsa.ImportCspBlob(keyData);
                        ctx.EncryptCtx.CryptoTransform = null;
                    }
                    break;

                case AlgorithmType.DSA:
                case AlgorithmType.DSA_SHA1:
                    if (keyData == null)
                    {
                        ctx.EncryptCtx.CryptoObject = kd.KeyCsp as IDisposable;
                    }
                    else
                    {
                        DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
                        ctx.EncryptCtx.CryptoObject    = dsa;
                        ctx.EncryptCtx.CryptoTransform = null;
                        dsa.ImportCspBlob(keyData);
                    }
                    break;

                default:
                    return(false);
                }
            }
            catch (Exception e)
            {
                Debug.Print(e.ToString());
                return(false);
            }

            return(true);
        }
예제 #5
0
        public bool SetAttributeValue(int session, int hObject, IntPtr pTemplate, int ulCount)
        {
            try
            {
                SessionData    ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);
                CryptokiObject obj = ctx.ObjectCtx.GetObject(hObject);

                if (obj == null)
                {
                    return(false);
                }

                if (obj.Type == CryptokiObjectType.Cert)
                {
                    X509Certificate2 cert = obj.Data as X509Certificate2;
                    bool             fSave = false;
                    bool             fDelete = false;
                    string           group = "", fileName = "";
                    uint             len = 0;
                    byte[]           data;

                    for (int i = 0; i < (int)ulCount; i++)
                    {
                        CryptokiAttribute attrib = new CryptokiAttribute();
                        Marshal.PtrToStructure(pTemplate, attrib);

                        switch ((CryptokiAttribType)attrib.type)
                        {
                        case CryptokiAttribType.Persist:
                            fSave   = Marshal.ReadInt32(attrib.pValue) == 1;
                            fDelete = !fSave;
                            break;

                        case CryptokiAttribType.Label:
                            len = attrib.ulValueLen;

                            data = new byte[len];

                            Marshal.Copy(attrib.pValue, data, 0, (int)len);

                            group = UTF8Encoding.UTF8.GetString(data);

                            break;

                        case CryptokiAttribType.ObjectID:
                            len = attrib.ulValueLen;

                            data = new byte[len];

                            Marshal.Copy(attrib.pValue, data, 0, (int)len);

                            fileName = UTF8Encoding.UTF8.GetString(data);

                            break;

                        default:
                            return(false);
                        }

                        pTemplate += Marshal.SizeOf(attrib);
                    }

                    if (fDelete)
                    {
                        ctx.ObjectCtx.DestroyObject(hObject);
                    }
                    else if (fSave)
                    {
                        // TODO: Store in persistant storage for emulator

                        obj.Properties["FileName"] = fileName;
                        obj.Properties["Group"]    = group;
                    }
                    else
                    {
                        return(false);
                    }
                }

                return(true);
            }
            catch
            {
                return(false);
            }
        }
예제 #6
0
        public bool GetAttributeValue(int session, int hObject, IntPtr pTemplate, int ulCount)
        {
            try
            {
                SessionData    ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);
                CryptokiObject obj = ctx.ObjectCtx.GetObject(hObject);

                if (obj == null)
                {
                    return(false);
                }

                DSAParameters dsaParms    = new DSAParameters();
                bool          hasDsaParms = false;
                int           valueLen    = 0;
                RSAParameters rsaParms    = new RSAParameters();

                while (ulCount-- > 0)
                {
                    CryptokiAttribute attrib = new CryptokiAttribute();
                    Marshal.PtrToStructure(pTemplate, attrib);

                    if (obj.Type == CryptokiObjectType.Cert)
                    {
                        X509Certificate2 cert = (X509Certificate2)obj.Data;
                        switch ((CryptokiAttribType)attrib.type)
                        {
                        case CryptokiAttribType.Class:
                            Marshal.WriteInt32(attrib.pValue, (int)CryptokiClass.CERTIFICATE);
                            valueLen = 4;
                            break;

                        case CryptokiAttribType.Private:
                            Marshal.WriteInt32(attrib.pValue, cert.HasPrivateKey ? 1 : 0);
                            valueLen = 4;
                            break;

                        case CryptokiAttribType.KeyType:
                            switch (cert.GetKeyAlgorithm())
                            {
                            case "1.2.840.113549.1.1.1":
                                Marshal.WriteInt32(attrib.pValue, (int)KeyType.RSA);
                                break;

                            default:
                                Marshal.WriteInt32(attrib.pValue, -1);
                                break;
                            }
                            valueLen = 4;
                            break;

                        case CryptokiAttribType.Issuer:
                        {
                            byte [] data = UTF8Encoding.UTF8.GetBytes(cert.Issuer);
                            Marshal.Copy(data, 0, attrib.pValue, data.Length);
                            valueLen = data.Length;
                        }
                        break;

                        case CryptokiAttribType.Subject:
                        {
                            byte [] data = UTF8Encoding.UTF8.GetBytes(cert.Subject);
                            Marshal.Copy(data, 0, attrib.pValue, data.Length);
                            valueLen = data.Length;
                        }
                        break;

                        case CryptokiAttribType.SerialNumber:
                        {
                            byte[] data = cert.GetSerialNumber();
                            Marshal.Copy(data, 0, attrib.pValue, data.Length);
                            valueLen = data.Length;
                        }
                        break;

                        case CryptokiAttribType.PublicExponent:
                        {
                        }
                        break;

                        case CryptokiAttribType.StartDate:
                        case CryptokiAttribType.EndDate:
                        {
                            DATE_TIME_INFO dti = new DATE_TIME_INFO();
                            DateTime       dt  = (CryptokiAttribType)attrib.type == CryptokiAttribType.StartDate ? cert.NotBefore : cert.NotAfter;

                            dti.year     = dt.Year;
                            dti.month    = dt.Month;
                            dti.day      = dt.Day;
                            dti.hour     = dt.Hour;
                            dti.minute   = dt.Minute;
                            dti.second   = dt.Second;
                            dti.msec     = dt.Millisecond;
                            dti.tzOffset = TimeZoneInfo.Local.BaseUtcOffset.Hours;

                            Marshal.StructureToPtr(dti, attrib.pValue, true);
                            valueLen = Marshal.SizeOf(dti);
                        }
                        break;

                        case CryptokiAttribType.MechanismType:
                        {
                            switch (cert.SignatureAlgorithm.Value)
                            {
                            case "1.2.840.113549.1.1.5":
                                Marshal.WriteInt32(attrib.pValue, (int)AlgorithmType.SHA1_RSA_PKCS);
                                break;

                            case "1.2.840.113549.1.1.4":
                                Marshal.WriteInt32(attrib.pValue, (int)AlgorithmType.MD5_RSA_PKCS);
                                break;

                            case "1.2.840.113549.1.1.11":
                                Marshal.WriteInt32(attrib.pValue, (int)AlgorithmType.SHA256_RSA_PKCS);
                                break;

                            case "1.2.840.113549.1.1.12":
                                Marshal.WriteInt32(attrib.pValue, (int)AlgorithmType.SHA384_RSA_PKCS);
                                break;

                            case "1.2.840.113549.1.1.13":
                                Marshal.WriteInt32(attrib.pValue, (int)AlgorithmType.SHA512_RSA_PKCS);
                                break;
                            }
                            valueLen = 4;
                        }
                        break;

                        case CryptokiAttribType.Value:
                            valueLen = cert.RawData.Length;
                            Marshal.Copy(cert.RawData, 0, attrib.pValue, valueLen);
                            break;

                        case CryptokiAttribType.ValueLen:
                            Marshal.WriteInt32(attrib.pValue, valueLen);
                            break;
                        }
                    }
                    else if (obj.Type == CryptokiObjectType.Key)
                    {
                        object key = ((KeyData)obj.Data).KeyCsp;

                        switch ((CryptokiAttribType)attrib.type)
                        {
                        case CryptokiAttribType.Class:
                            Marshal.WriteInt32(attrib.pValue, (int)CryptokiClass.OTP_KEY);
                            valueLen = 4;
                            break;

                        case CryptokiAttribType.PrivateExponent:
                            if (key is DSACryptoServiceProvider)
                            {
                                if (!hasDsaParms)
                                {
                                    dsaParms = ((DSACryptoServiceProvider)key).ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, dsaParms.X.Length);

                                Marshal.Copy(dsaParms.X, 0, attrib.pValue, valueLen);
                            }
                            else if (key is AesCryptoServiceProvider)
                            {
                                AesCryptoServiceProvider aes = (AesCryptoServiceProvider)key;

                                valueLen = Math.Min((int)attrib.ulValueLen, aes.Key.Length);

                                Marshal.Copy(aes.Key, 0, attrib.pValue, valueLen);
                            }
                            else if (key is KeyManagementDriver.SecretKey)
                            {
                                KeyManagementDriver.SecretKey sk = (KeyManagementDriver.SecretKey)key;

                                valueLen = Math.Min((int)attrib.ulValueLen, sk.Data.Length);

                                Marshal.Copy(sk.Data, 0, attrib.pValue, valueLen);
                            }
                            else if (key is RSACryptoServiceProvider)
                            {
                                RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)key;

                                if (rsaParms.Modulus == null)
                                {
                                    rsaParms = rsa.ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, rsaParms.D.Length);

                                Marshal.Copy(rsaParms.D, 0, attrib.pValue, valueLen);
                            }
                            break;

                        case CryptokiAttribType.PublicExponent:
                            if (key is DSACryptoServiceProvider)
                            {
                                if (!hasDsaParms)
                                {
                                    dsaParms = ((DSACryptoServiceProvider)key).ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, dsaParms.Y.Length);

                                Marshal.Copy(dsaParms.Y, 0, attrib.pValue, valueLen);
                            }
                            else if (key is ECDiffieHellman)
                            {
                                ECDiffieHellman ecdh = (ECDiffieHellman)key;

                                byte[] pubKey = ecdh.PublicKey.ToByteArray();

                                valueLen = Math.Min((int)attrib.ulValueLen, pubKey.Length - 8);

                                Marshal.Copy(pubKey, 8, attrib.pValue, valueLen);
                            }
                            else if (key is RSACryptoServiceProvider)
                            {
                                RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)key;

                                if (rsaParms.Modulus == null)
                                {
                                    rsaParms = rsa.ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, rsaParms.Exponent.Length);

                                Marshal.Copy(rsaParms.Exponent, 0, attrib.pValue, valueLen);
                            }
                            break;

                        case CryptokiAttribType.Prime:
                            if (key is DSACryptoServiceProvider)
                            {
                                if (!hasDsaParms)
                                {
                                    dsaParms = ((DSACryptoServiceProvider)key).ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, dsaParms.P.Length);

                                Marshal.Copy(dsaParms.P, 0, attrib.pValue, valueLen);
                            }
                            break;

                        case CryptokiAttribType.Subprime:
                            if (key is DSACryptoServiceProvider)
                            {
                                if (!hasDsaParms)
                                {
                                    dsaParms = ((DSACryptoServiceProvider)key).ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, dsaParms.Q.Length);

                                Marshal.Copy(dsaParms.Q, 0, attrib.pValue, valueLen);
                            }
                            break;

                        case CryptokiAttribType.Base:
                            if (key is DSACryptoServiceProvider)
                            {
                                if (!hasDsaParms)
                                {
                                    dsaParms = ((DSACryptoServiceProvider)key).ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, dsaParms.G.Length);

                                Marshal.Copy(dsaParms.G, 0, attrib.pValue, valueLen);
                            }
                            break;

                        case CryptokiAttribType.ValueLen:
                            Marshal.WriteInt32(attrib.pValue, valueLen);
                            break;

                        case CryptokiAttribType.KeyType:
                            if (key is DSACryptoServiceProvider)
                            {
                                Marshal.WriteInt32(attrib.pValue, (int)KeyType.DSA);
                            }
                            else if (key is RSACryptoServiceProvider)
                            {
                                Marshal.WriteInt32(attrib.pValue, (int)KeyType.RSA);
                            }
                            else if (key is ECDsaCng)
                            {
                                Marshal.WriteInt32(attrib.pValue, (int)KeyType.ECDSA);
                            }
                            else if (key is ECDiffieHellman)
                            {
                                Marshal.WriteInt32(attrib.pValue, (int)KeyType.EC);
                            }
                            else if (key is AesCryptoServiceProvider)
                            {
                                Marshal.WriteInt32(attrib.pValue, (int)KeyType.AES);
                            }
                            else if (key is TripleDESCryptoServiceProvider)
                            {
                                Marshal.WriteInt32(attrib.pValue, (int)KeyType.DES3);
                            }
                            else if (key is KeyManagementDriver.SecretKey)
                            {
                                Marshal.WriteInt32(attrib.pValue, (int)KeyType.GENERIC_SECRET);
                            }
                            break;

                        case CryptokiAttribType.ValueBits:
                            if (key is DSACryptoServiceProvider)
                            {
                                Marshal.WriteInt32(attrib.pValue, ((DSACryptoServiceProvider)key).KeySize);
                            }
                            else if (key is RSACryptoServiceProvider)
                            {
                                Marshal.WriteInt32(attrib.pValue, ((RSACryptoServiceProvider)key).KeySize);
                            }
                            else if (key is ECDsaCng)
                            {
                                Marshal.WriteInt32(attrib.pValue, ((ECDsaCng)key).KeySize);
                            }
                            else if (key is ECDiffieHellman)
                            {
                                Marshal.WriteInt32(attrib.pValue, ((ECDiffieHellman)key).KeySize);
                            }
                            else if (key is AesCryptoServiceProvider)
                            {
                                Marshal.WriteInt32(attrib.pValue, ((AesCryptoServiceProvider)key).KeySize);
                            }
                            else if (key is TripleDESCryptoServiceProvider)
                            {
                                Marshal.WriteInt32(attrib.pValue, ((TripleDESCryptoServiceProvider)key).KeySize);
                            }
                            else if (key is KeyManagementDriver.SecretKey)
                            {
                                Marshal.WriteInt32(attrib.pValue, ((KeyManagementDriver.SecretKey)key).Size);
                            }
                            break;

                        case CryptokiAttribType.Value:
                            if (key is AesCryptoServiceProvider)
                            {
                                AesCryptoServiceProvider aes = (AesCryptoServiceProvider)key;

                                valueLen = Math.Min((int)attrib.ulValueLen, aes.Key.Length);

                                Marshal.Copy(aes.Key, 0, attrib.pValue, valueLen);
                            }
                            else if (key is KeyManagementDriver.SecretKey)
                            {
                                KeyManagementDriver.SecretKey sk = (KeyManagementDriver.SecretKey)key;

                                valueLen = Math.Min((int)attrib.ulValueLen, sk.Data.Length);

                                Marshal.Copy(sk.Data, 0, attrib.pValue, valueLen);
                            }
                            else if (key is ECDiffieHellman)
                            {
                                ECDiffieHellman ecdh = (ECDiffieHellman)key;

                                byte[] pubKey = ecdh.PublicKey.ToByteArray();

                                valueLen = Math.Min((int)attrib.ulValueLen, pubKey.Length);

                                Marshal.Copy(pubKey, 0, attrib.pValue, valueLen);
                            }
                            break;

                        case CryptokiAttribType.Modulus:
                            if (key is RSACryptoServiceProvider)
                            {
                                RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)key;

                                if (rsaParms.Modulus == null)
                                {
                                    rsaParms = rsa.ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, rsaParms.Modulus.Length);

                                Marshal.Copy(rsaParms.Modulus, 0, attrib.pValue, valueLen);
                            }
                            break;

                        case CryptokiAttribType.Prime1:
                            if (key is RSACryptoServiceProvider)
                            {
                                RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)key;

                                if (rsaParms.Modulus == null)
                                {
                                    rsaParms = rsa.ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, rsaParms.P.Length);

                                Marshal.Copy(rsaParms.P, 0, attrib.pValue, valueLen);
                            }
                            break;

                        case CryptokiAttribType.Prime2:
                            if (key is RSACryptoServiceProvider)
                            {
                                RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)key;

                                if (rsaParms.Modulus == null)
                                {
                                    rsaParms = rsa.ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, rsaParms.Q.Length);

                                Marshal.Copy(rsaParms.Q, 0, attrib.pValue, valueLen);
                            }
                            break;

                        case CryptokiAttribType.Exponent1:
                            if (key is RSACryptoServiceProvider)
                            {
                                RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)key;

                                if (rsaParms.Modulus == null)
                                {
                                    rsaParms = rsa.ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, rsaParms.DP.Length);

                                Marshal.Copy(rsaParms.DP, 0, attrib.pValue, valueLen);
                            }
                            break;

                        case CryptokiAttribType.Exponent2:
                            if (key is RSACryptoServiceProvider)
                            {
                                RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)key;

                                if (rsaParms.Modulus == null)
                                {
                                    rsaParms = rsa.ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, rsaParms.DQ.Length);

                                Marshal.Copy(rsaParms.DQ, 0, attrib.pValue, valueLen);
                            }
                            break;

                        case CryptokiAttribType.Coefficent:
                            if (key is RSACryptoServiceProvider)
                            {
                                RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)key;

                                if (rsaParms.Modulus == null)
                                {
                                    rsaParms = rsa.ExportParameters(true);
                                }

                                valueLen = Math.Min((int)attrib.ulValueLen, rsaParms.InverseQ.Length);

                                Marshal.Copy(rsaParms.InverseQ, 0, attrib.pValue, valueLen);
                            }
                            break;
                        }
                    }

                    pTemplate += Marshal.SizeOf(attrib);
                }
            }
            catch
            {
                return(false);
            }

            return(true);
        }