Some samples on PKCS11Interop

156 views
Skip to first unread message

olivie...@gmail.com

unread,
Jul 17, 2019, 9:08:52 AM7/17/19
to Pkcs11Interop
First, I have created a shortcut to create attribute lists

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

olivie...@gmail.com

unread,
Jul 17, 2019, 9:12:42 AM7/17/19
to Pkcs11Interop
Here's the shortcut for creating AttributesList :

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

Reply all
Reply to author
Forward
0 new messages