Example #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>
        /// 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));
            }
        }
        /// <summary>
        /// Requests PIN code for private key stored on PKCS#11 token
        /// </summary>
        /// <param name="certificateContext">Internal context for Pkcs11X509Certificate2 class</param>
        /// <returns>PIN code</returns>
        public static byte[] GetKeyPin(Pkcs11X509CertificateContext certificateContext)
        {
            IPinProvider pinProvider = certificateContext.TokenContext.SlotContext.StoreContext.PinProvider;

            Pkcs11X509StoreInfo       storeInfo       = certificateContext.TokenContext.SlotContext.StoreContext.StoreInfo;
            Pkcs11SlotInfo            slotInfo        = certificateContext.TokenContext.SlotContext.SlotInfo;
            Pkcs11TokenInfo           tokenInfo       = certificateContext.TokenContext.TokenInfo;
            Pkcs11X509CertificateInfo certificateInfo = certificateContext.CertificateInfo;

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

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

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

            return(getPinResult.Pin);
        }