/// <summary>
        /// Generates a digital signature for the specified hash value
        /// </summary>
        /// <param name="hash">The hash value of the data that is being signed</param>
        /// <returns>A digital signature that consists of the given hash value encrypted with the private key</returns>
        public override byte[] SignHash(byte[] hash)
        {
            if (hash == null || hash.Length == 0)
            {
                throw new ArgumentNullException(nameof(hash));
            }

            using (ISession session = _certContext.TokenContext.SlotContext.Slot.OpenSession(SessionType.ReadOnly))
                using (IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_ECDSA))
                {
                    if (_certContext.KeyUsageRequiresLogin)
                    {
                        return(session.Sign(mechanism, _certContext.PrivKeyHandle, PinProviderUtils.GetKeyPin(_certContext), hash));
                    }
                    else
                    {
                        return(session.Sign(mechanism, _certContext.PrivKeyHandle, hash));
                    }
                }
        }
        /// <summary>
        /// Finds all X.509 certificates present on token
        /// </summary>
        /// <returns>All X.509 certificates present on token</returns>
        private List <Pkcs11X509Certificate> FindCertificates()
        {
            var certificates = new List <Pkcs11X509Certificate>();

            if (_tokenContext.TokenInfo.Initialized)
            {
                using (Session session = _tokenContext.SlotContext.Slot.OpenSession(SessionType.ReadOnly))
                {
                    if (!this.SessionIsAuthenticated(session))
                    {
                        try
                        {
                            byte[] pin = PinProviderUtils.GetTokenPin(_tokenContext);
                            _tokenContext.AuthenticatedSession.Login(CKU.CKU_USER, pin);
                        }
                        catch (LoginCancelledException)
                        {
                            // Ignore and continue without login
                        }
                    }

                    var searchTemplate = new List <ObjectAttribute>()
                    {
                        new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE),
                        new ObjectAttribute(CKA.CKA_TOKEN, true),
                        new ObjectAttribute(CKA.CKA_CERTIFICATE_TYPE, CKC.CKC_X_509)
                    };

                    foreach (ObjectHandle certHandle in session.FindAllObjects(searchTemplate))
                    {
                        var pkcs11cert = new Pkcs11X509Certificate(certHandle, _tokenContext);
                        certificates.Add(pkcs11cert);
                    }
                }
            }

            return(certificates);
        }
예제 #3
0
        /// <summary>
        /// Computes the signature for the specified hash value by encrypting it with the private key using the specified padding
        /// </summary>
        /// <param name="hash">The hash value of the data to be signed</param>
        /// <param name="hashAlgorithm">The hash algorithm used to create the hash value of the data</param>
        /// <param name="padding">The padding</param>
        /// <returns>The RSA signature for the specified hash value</returns>
        public override byte[] SignHash(byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
        {
            if (hash == null || hash.Length == 0)
            {
                throw new ArgumentNullException(nameof(hash));
            }

            if (hashAlgorithm == null)
            {
                throw new ArgumentNullException(nameof(hashAlgorithm));
            }

            if (padding == null)
            {
                throw new ArgumentNullException(nameof(padding));
            }

            if (padding == RSASignaturePadding.Pkcs1)
            {
                byte[] pkcs1DigestInfo = CreatePkcs1DigestInfo(hash, hashAlgorithm);
                if (pkcs1DigestInfo == null)
                {
                    throw new NotSupportedException(string.Format("Algorithm {0} is not supported", hashAlgorithm.Name));
                }

                using (ISession session = _certContext.TokenContext.SlotContext.Slot.OpenSession(SessionType.ReadOnly))
                    using (IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_RSA_PKCS))
                    {
                        if (_certContext.KeyUsageRequiresLogin)
                        {
                            return(session.Sign(mechanism, _certContext.PrivKeyHandle, PinProviderUtils.GetKeyPin(_certContext), pkcs1DigestInfo));
                        }
                        else
                        {
                            return(session.Sign(mechanism, _certContext.PrivKeyHandle, pkcs1DigestInfo));
                        }
                    }
            }
            else if (padding == RSASignaturePadding.Pss)
            {
                IMechanismParamsFactory mechanismParamsFactory = _certContext.TokenContext.SlotContext.Slot.Factories.MechanismParamsFactory;

                ICkRsaPkcsPssParams pssMechanismParams = CreateCkRsaPkcsPssParams(mechanismParamsFactory, hash, hashAlgorithm);
                if (pssMechanismParams == null)
                {
                    throw new NotSupportedException(string.Format("Algorithm {0} is not supported", hashAlgorithm.Name));
                }

                using (ISession session = _certContext.TokenContext.SlotContext.Slot.OpenSession(SessionType.ReadOnly))
                    using (IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_RSA_PKCS_PSS, pssMechanismParams))
                    {
                        if (_certContext.KeyUsageRequiresLogin)
                        {
                            return(session.Sign(mechanism, _certContext.PrivKeyHandle, PinProviderUtils.GetKeyPin(_certContext), hash));
                        }
                        else
                        {
                            return(session.Sign(mechanism, _certContext.PrivKeyHandle, hash));
                        }
                    }
            }
            else
            {
                throw new NotSupportedException(string.Format("Padding {0} is not supported", padding));
            }
        }