Ejemplo n.º 1
0
 /// <summary>
 /// Creates new instance of Pkcs11X509Certificate2Context class
 /// </summary>
 /// <param name="certificateInfo">Detailed information about X.509 certificate stored on PKCS#11 token</param>
 /// <param name="certHandle">High level PKCS#11 object handle of certificate object</param>
 /// <param name="privKeyHandle">High level PKCS#11 object handle of private key object</param>
 /// <param name="pubKeyHandle">High level PKCS#11 object handle of public key object</param>
 /// <param name="keyUsageRequiresLogin">Flag indicating whether key usage requires context specific login to be perfromed</param>
 /// <param name="tokenContext">Internal context for Pkcs11Token class</param>
 internal Pkcs11X509CertificateContext(Pkcs11X509CertificateInfo certificateInfo, IObjectHandle certHandle, IObjectHandle privKeyHandle, IObjectHandle pubKeyHandle, bool keyUsageRequiresLogin, Pkcs11TokenContext tokenContext)
 {
     _certificateInfo       = certificateInfo ?? throw new ArgumentNullException(nameof(certificateInfo));
     _certHandle            = certHandle ?? throw new ArgumentNullException(nameof(certHandle));
     _privKeyHandle         = privKeyHandle;
     _pubKeyHandle          = pubKeyHandle;
     _keyUsageRequiresLogin = keyUsageRequiresLogin;
     _tokenContext          = tokenContext ?? throw new ArgumentNullException(nameof(tokenContext));
 }
        /// <summary>
        /// Creates new instance of Pkcs11Token class
        /// </summary>
        /// <param name="slotContext">Internal context for Pkcs11Slot class</param>
        internal Pkcs11Token(Pkcs11SlotContext slotContext)
        {
            if (slotContext == null)
            {
                throw new ArgumentNullException(nameof(slotContext));
            }

            _tokenContext = this.GetTokenContext(slotContext);
            // Note: _certificates are loaded on first access
        }
        /// <summary>
        /// Creates new instance of Pkcs11X509Certificate2 class
        /// </summary>
        /// <param name="certHandle">High level PKCS#11 object handle of certificate object</param>
        /// <param name="tokenContext">Internal context for Pkcs11Token class</param>
        internal Pkcs11X509Certificate(IObjectHandle certHandle, Pkcs11TokenContext tokenContext)
        {
            if (certHandle == null)
            {
                throw new ArgumentNullException(nameof(certHandle));
            }

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

            _certContext = GetCertificateContext(certHandle, tokenContext);
        }
        /// <summary>
        /// Disposes object
        /// </summary>
        /// <param name="disposing">Flag indicating whether managed resources should be disposed</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // Dispose managed objects

                    if (_tokenContext != null)
                    {
                        _tokenContext.Dispose();
                        _tokenContext = null;
                    }
                }

                // Dispose unmanaged objects

                _disposed = true;
            }
        }
        /// <summary>
        /// Requests PIN code for PKCS#11 token
        /// </summary>
        /// <param name="tokenContext">Internal context for Pkcs11Token class</param>
        /// <returns>PIN code</returns>
        public static byte[] GetTokenPin(Pkcs11TokenContext tokenContext)
        {
            IPinProvider pinProvider = tokenContext.SlotContext.StoreContext.PinProvider;

            Pkcs11X509StoreInfo storeInfo = tokenContext.SlotContext.StoreContext.StoreInfo;
            Pkcs11SlotInfo      slotInfo  = tokenContext.SlotContext.SlotInfo;
            Pkcs11TokenInfo     tokenInfo = tokenContext.TokenInfo;

            GetPinResult getPinResult = pinProvider.GetTokenPin(storeInfo, slotInfo, tokenInfo);

            if (getPinResult == null)
            {
                throw new Exception("Invalid response from IPinProvider");
            }

            if (getPinResult.Cancel)
            {
                throw new LoginCancelledException("Login with token pin was cancelled");
            }

            return(getPinResult.Pin);
        }
        /// <summary>
        /// Constructs internal context for Pkcs11X509Certificate class
        /// </summary>
        /// <param name="certHandle">High level PKCS#11 object handle of certificate object</param>
        /// <param name="tokenContext">Internal context for Pkcs11Token class</param>
        /// <returns>Internal context for Pkcs11X509Certificate class</returns>
        private Pkcs11X509CertificateContext GetCertificateContext(IObjectHandle certHandle, Pkcs11TokenContext tokenContext)
        {
            using (ISession session = tokenContext.SlotContext.Slot.OpenSession(SessionType.ReadOnly))
            {
                List <IObjectAttribute> objectAttributes = session.GetAttributeValue(certHandle, new List <CKA>()
                {
                    CKA.CKA_ID, CKA.CKA_LABEL, CKA.CKA_VALUE
                });

                byte[] ckaId    = objectAttributes[0].GetValueAsByteArray();
                string ckaLabel = objectAttributes[1].GetValueAsString();
                byte[] ckaValue = objectAttributes[2].GetValueAsByteArray();

                var certInfo = new Pkcs11X509CertificateInfo(ckaId, ckaLabel, ckaValue);

                IObjectHandle privKeyHandle = FindKey(session, CKO.CKO_PRIVATE_KEY, ckaId, ckaLabel);
                IObjectHandle pubKeyHandle  = FindKey(session, CKO.CKO_PUBLIC_KEY, ckaId, ckaLabel);

                bool keyUsageRequiresLogin = (privKeyHandle == null) ? false : GetCkaAlwaysAuthenticateValue(session, privKeyHandle);

                return(new Pkcs11X509CertificateContext(certInfo, certHandle, privKeyHandle, pubKeyHandle, keyUsageRequiresLogin, tokenContext));
            }
        }