Both files .pfx and .p12 contains a key pair (public key + private key) and the related certificate. Importing a pfx or a p12 means importing the public key, the private key and the certificate as well. Usually a pfx or a p12 file is protected by a password, so you need to know the password to import it in the token
This snippet opens a .pfx or a .p12 file and create an X509Certificate2 object:
X509Certificate2 cert = new X509Certificate2(filepath, password, X509KeyStorageFlags.Exportable);
string id = "mykeyid";
string label = "mylabel";
boolean private = true;
boolean modifiable = false;
importKeyPair(cert, id, label, private, modifiable);
importCertificate(cert, id, label, modifiable);
this is the implementation of the importKey function:
private bool importKeyPair(X509Certificate2 cert, string id, string label, bool priv, bool modifiable)
{
if (!cert.HasPrivateKey)
{
showError("Certificate doesn't have private key. Import failed!");
return false;
}
AsymmetricAlgorithm keyPair = cert.PrivateKey;
if (keyPair is RSA)
{
RSAParameters keyParams = ((RSA)keyPair).ExportParameters(true);
CryptokiCollection template = new CryptokiCollection();
template.Add(new ObjectAttribute(ObjectAttribute.CKA_CLASS, CryptokiObject.CKO_PRIVATE_KEY));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_KEY_TYPE, Key.CKK_RSA));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_SUBJECT, cert.SubjectName.RawData));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_ID, id));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_LABEL, label));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_TOKEN, true));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_MODULUS, keyParams.Modulus));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_PUBLIC_EXPONENT, keyParams.Exponent));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_PRIVATE_EXPONENT, keyParams.D));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_PRIVATE, priv));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_MODIFIABLE, modifiable));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_EXTRACTABLE, false));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_DECRYPT, true));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_SIGN, true));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_UNWRAP, true));
CryptokiObject priKey = CurrentSession.Objects.Create(template);
}
return true;
}
this is the implementation of the importCertificate function
private bool importCertificate(X509Certificate2 cert, string id, string label, bool modifiable)
{
CryptokiCollection template = new CryptokiCollection();
template.Add(new ObjectAttribute(ObjectAttribute.CKA_CLASS, CryptokiObject.CKO_CERTIFICATE));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_CERTIFICATE_TYPE, Certificate.CKC_X_509));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_SUBJECT, cert.SubjectName.RawData));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_ISSUER, cert.Issuer));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_SERIAL_NUMBER, cert.SerialNumber));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_ID, id));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_LABEL, label));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_TOKEN, true));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_VALUE, cert.RawData));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_MODIFIABLE, modifiable));
CryptokiObject certificate = CurrentSession.Objects.Create(template);
return true;
}