Create KeyPair :
public void CreateRSAKeyPair(Guid id, string label, X509Name subject, ulong keyLength, byte[] exponent, out IObjectHandle publicKeyObjectHandle, out IObjectHandle privateKeyObjectHandle)
{
var publicKeyAttributes = Session.CreateAttributesList(
(CKA.CKA_ID, id),
(CKA.CKA_LABEL, label),
(CKA.CKA_SUBJECT, subject),
(CKA.CKA_PRIVATE, false),
(CKA.CKA_TOKEN, true),
(CKA.CKA_ENCRYPT, true),
(CKA.CKA_VERIFY, true),
(CKA.CKA_WRAP, true),
(CKA.CKA_MODULUS_BITS, keyLength),
(CKA.CKA_PUBLIC_EXPONENT, exponent)
);
var privateKeyAttributes = Session.CreateAttributesList(
(CKA.CKA_ID, id),
(CKA.CKA_LABEL, label),
(CKA.CKA_SUBJECT, subject),
(CKA.CKA_TOKEN, true),
(CKA.CKA_PRIVATE, true),
(CKA.CKA_SENSITIVE, true),
(CKA.CKA_DECRYPT, true),
(CKA.CKA_SIGN, true),
(CKA.CKA_UNWRAP, true)
);
var mechanismInfo = Slot.GetMechanismInfo(CKM.CKM_RSA_X_509);
Session.GenerateKeyPair(Session.Factories.MechanismFactory.Create(CKM.CKM_RSA_PKCS_KEY_PAIR_GEN), publicKeyAttributes, privateKeyAttributes, out publicKeyObjectHandle, out privateKeyObjectHandle);
}
Import Certificate :
public IObjectHandle ImportCertificate(Guid Id, string label, X509Certificate cert)
{
IObjectHandle certificateId;
var certificateAttributes = Session.CreateAttributesList(
(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE),
(CKA.CKA_CERTIFICATE_TYPE, CKC.CKC_X_509),
(CKA.CKA_ID, Id),
(CKA.CKA_LABEL, label),
(CKA.CKA_SUBJECT, cert.SubjectDN.ToString(true, X509Name.DefaultSymbols)),
(CKA.CKA_TOKEN, true),
(CKA.CKA_PRIVATE, false),
(CKA.CKA_ISSUER, cert.IssuerDN),
(CKA.CKA_SERIAL_NUMBER, cert.SerialNumber.ToByteArray()),
(CKA.CKA_VALUE, cert)
);
certificateId = Session.CreateObject(certificateAttributes);
return certificateId;
}
Import PublicKey :
public IObjectHandle ImportPublicKey(Guid Id, string label, X509Name subject, RsaKeyParameters publicKey)
{
IObjectHandle publicKeyId;
//SubjectPublicKeyInfo pki = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
var publicKeyAttributes = Session.CreateAttributesList(
(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY),
(CKA.CKA_ID, Id),
(CKA.CKA_LABEL, label),
(CKA.CKA_SUBJECT, subject),
(CKA.CKA_KEY_TYPE, CKK.CKK_RSA),
(CKA.CKA_TOKEN, true),
(CKA.CKA_PRIVATE, false),
(CKA.CKA_ENCRYPT, true),
(CKA.CKA_VERIFY, true),
(CKA.CKA_VERIFY_RECOVER, false),
(CKA.CKA_WRAP, true),
(CKA.CKA_PUBLIC_EXPONENT, publicKey.Exponent),
(CKA.CKA_MODULUS, publicKey.Modulus)
);
publicKeyId = Session.CreateObject(publicKeyAttributes);
return publicKeyId;
}
Import Private Key:
public IObjectHandle ImportPrivateKey(Guid Id, string label, X509Name subject, RsaPrivateCrtKeyParameters privateKey, bool exportable)
{
var privateKeyAttributes = Session.CreateAttributesList(
(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY),
(CKA.CKA_ID, Id),
(CKA.CKA_LABEL, label),
(CKA.CKA_SUBJECT, subject),
(CKA.CKA_KEY_TYPE, CKK.CKK_RSA),
(CKA.CKA_TOKEN, true),
(CKA.CKA_PRIVATE, !exportable),
(CKA.CKA_SENSITIVE, true),
(CKA.CKA_DECRYPT, true),
(CKA.CKA_SIGN, true),
(CKA.CKA_SIGN_RECOVER, true),
(CKA.CKA_UNWRAP, true)
);
var unencryptedPrivateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey).GetEncoded();
var privateKeyWrap = new MemoryStream();
using (var symetricKey = new TemporarySymetricKey(PKCS11Library, Session, CKK.CKK_DES3))
{
Session.Encrypt(
symetricKey.SymetricAlgorithm,
symetricKey.SymetricKeyHandle,
new MemoryStream(unencryptedPrivateKey),
privateKeyWrap);
privateKeyWrap.Position = 0;
byte[] encryptedPrivateKey = new byte[privateKeyWrap.Length];
privateKeyWrap.Read(encryptedPrivateKey, 0, encryptedPrivateKey.Length);
return Session.UnwrapKey(
symetricKey.SymetricAlgorithm,
symetricKey.SymetricKeyHandle,
encryptedPrivateKey,
privateKeyAttributes);
}
}
public class TemporarySymetricKey : IDisposable
{
private ISession session { get; }
public IObjectHandle SymetricKeyHandle { get; }
public IMechanism SymetricAlgorithm { get; }
public TemporarySymetricKey(IPkcs11Library pkcs11Library, ISession session, CKK KeyType)
{
this.session = session;
var tempKeyAttributes = session.CreateAttributesList(
(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY),
(CKA.CKA_KEY_TYPE, KeyType),
(CKA.CKA_ENCRYPT, true),
(CKA.CKA_UNWRAP, true)
);
SymetricKeyHandle = session.GenerateKey(pkcs11Library.Factories.MechanismFactory.Create(CKM.CKM_DES3_KEY_GEN), tempKeyAttributes);
SymetricAlgorithm = pkcs11Library.Factories.MechanismFactory.Create(CKM.CKM_DES3_CBC_PAD, session.GenerateRandom(8));
}
public void Dispose()
{
session.DestroyObject(SymetricKeyHandle);
}
}
public static List<IObjectAttribute> CreateAttributesList(this ISession Session, params (CKA Attribute, object Value)[] attributes)
{
var result = new List<IObjectAttribute>();
foreach (var attribute in attributes)
{
var method = ExtensionFunctionsType.GetMethod("CreateAttribute", BindingFlags.Static | BindingFlags.Public, null, new Type[] { Types.ISessionType, Types.CKAType, attribute.Value.GetType() }, null);
result.Add((IObjectAttribute)method.Invoke(null, new[] { Session, attribute.Attribute, attribute.Value }));
}
return result;
}
#region CreateAttribute
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute) => Session.Factories.ObjectAttributeFactory.Create(attribute);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, bool value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, byte[] value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, CKC value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, CKK value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, CKO value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, DateTime value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, X509Name value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value.ToString(true, X509Name.DefaultSymbols));
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, X509Certificate value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value.GetEncoded());
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, string value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, ulong value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, int value) => Session.Factories.ObjectAttributeFactory.Create(attribute, (ulong)value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, BigInteger value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value.ToByteArrayUnsigned());
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, List<CKM> value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, List<IObjectAttribute> value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, List<ulong> value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value);
public static IObjectAttribute CreateAttribute(this ISession Session, CKA attribute, Guid value) => Session.Factories.ObjectAttributeFactory.Create(attribute, value.ToByteArray());
#endregion