/// <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); }