ODP: CSR creation using pkcs11 dynamic engine
Piotr Lobacz
piotr.lobacz at softgent.com
Fri May 28 17:43:41 UTC 2021
Ok, i have found out that dotnet OpenSsl library has it's own code for verification is key private. For this it needs the whole data of private key from which this method:
static int HasNoPrivateKey(RSA* rsa)
which is in ./src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c of dotnet verifies occurence of all private parameters. Unfortunately from what i know private keys are not extractable from tokens because of CKA_EXTRACTABLE=false parameter.
Correct me if i'm wrong but from what i know about openssl, when i'm switching to a closed engine the whole cryptography is being made by the engine module. I think that there should be some other method verifing if key is private. Maybe somebody could give me a hint?
BR
Piotr
________________________________
Od: openssl-users <openssl-users-bounces at openssl.org> w imieniu użytkownika Piotr Lobacz <piotr.lobacz at softgent.com>
Wysłane: piątek, 28 maja 2021 13:10
Do: openssl-users at openssl.org <openssl-users at openssl.org>
Temat: CSR creation using pkcs11 dynamic engine
Hi all,
i'm trying to generate CSR using C# System.SecurityCryptography.Openssl library together with pkcs11 token library. The whole proces for this in command line works without any problems. For execution of this process i use command:
openssl req -new -subj '/C=PL/ST=Gdansk/L=Gdansk/CN=softgent.com/' -sha256 -engine pkcs11 -keyform engine -key "pkcs11:token=foo;object=tls;type=private;pin-value=1234567890"
The CSR is being generated and the output is like this:
-----BEGIN CERTIFICATE REQUEST-----
MIIBADCBqAIBADBGMQswCQYDVQQGEwJQTDEPMA0GA1UECAwGR2RhbnNrMQ8wDQYD
VQQHDAZHZGFuc2sxFTATBgNVBAMMDHNvZnRnZW50LmNvbTBZMBMGByqGSM49AgEG
CCqGSM49AwEHA0IABB7SwUzg8S+3iYNiqGPlidqwCdmuY8MV3RfKDiR5tL/I//Cn
9dGCBAfxTO23gb5pygIXB/qCARYuYLiGpE+tFo+gADAKBggqhkjOPQQDAgNHADBE
AiAI4kDGjeO/V3f7RWe34e00aZAubjLGuIRbxgmQosu7mQIgQDK3Nx22fJn80Cml
t3EQTa6x9oC4RtibFgWCxZ36Wyo=
-----END CERTIFICATE REQUEST-----
Now i'm trying to do all that programatically. In order to do that i have added some OpenSsl C# missing support for the engines and used the ENGINE_load_private_key method to retrieve SafeEvpPKeyHandle which is being retrieved (i have checked it with changing the key id value). The key which i'm using is "label_" + myKeyId i.e. "label_tls". The code looks like this:
public virtual SafeEvpPKeyHandle GetPrivKey(string label)
{
string keyId = "label_" + label;
SafeEvpPKeyHandle pkey = SafeNativeMethods.ENGINE_load_private_key(engine, keyId, IntPtr.Zero, IntPtr.Zero);
if(pkey.IsInvalid)
{
throw new InvalidOperationException("engine: unable to find private key with label='{label}'");
}
return pkey;
}
This is being returnin me SafeEvpPKeyHandle. The problem is in calling CreateSigningRequest from System.Security.Cryptography.OpenSsl.dll. I have this method:
public virtual string GetCSR(SafeEvpPKeyHandle pkey, string ext, HashAlgorithmName name)
{
// FIXME: determine key type
RSA rsa = new RSAOpenSsl(pkey);
CertificateRequest req = new CertificateRequest("CN=potato", rsa, name, RSASignaturePadding.Pkcs1); // this method is only for RSA key different is for EC, DSA etc.
byte[] requestDer = req.CreateSigningRequest();
string requestPem = new string(PemEncoding.Write("CERTIFICATE REQUEST", requestDer));
return requestPem;
}
and i'm getting this error:
Unhandled exception. Interop+Crypto+OpenSslCryptographicException: error:04075093:rsa routines:RSA_sign:value missing
at System.Security.Cryptography.RSAOpenSsl.TrySignHash(ReadOnlySpan`1 hash, Span`1 destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, Boolean allocateSignature, Int32& bytesWritten, Byte[]& signature)
at System.Security.Cryptography.RSAOpenSsl.SignHash(Byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.SignData(Byte[] data, Int32 offset, Int32 count, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.SignData(Byte[] data, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.X509Certificates.RSAPkcs1X509SignatureGenerator.SignData(Byte[] data, HashAlgorithmName hashAlgorithm)
at System.Security.Cryptography.X509Certificates.Pkcs10CertificationRequestInfo.ToPkcs10Request(X509SignatureGenerator signatureGenerator, HashAlgorithmName hashAlgorithm)
at System.Security.Cryptography.X509Certificates.CertificateRequest.CreateSigningRequest(X509SignatureGenerator signatureGenerator)
at System.Security.Cryptography.X509Certificates.CertificateRequest.CreateSigningRequest()
at System.Security.Cryptography.Engine.GetCSR(SafeEvpPKeyHandle pkey, String ext, HashAlgorithmName name) in /home/plobacz/workspace/OpenSsl.DynamicEngine/Engine.cs:line 72
at Flexgent.Services.CryptoSubsystem.CryptoSubsystem.Configure(String config) in /home/plobacz/workspace/crypto-subsystem/flexgent/extensions/security/crypto-subsystem/src/CryptoSubsystem.cs:line 145
at Flexgent.Core.Service.Flexgent.Core.IService.Configure(String config) in /home/plobacz/workspace/crypto-subsystem/flexgent/core/library/src/Classes/Service.cs:line 42
at Flexgent.Core.ServiceRunner`1.Run(ServiceRunnerOptions options, Action`1 mainLoop, IEnumerable`1 standaloneConnectInterfaces) in /home/plobacz/workspace/crypto-subsystem/flexgent/core/library/src/Classes/ServiceRunner.cs:line 50
at Flexgent.Services.CryptoSubsystem.CryptoSubsystemMain.<>c.<Main>b__1_0(ServiceRunnerOptions o) in /home/plobacz/workspace/crypto-subsystem/flexgent/extensions/security/crypto-subsystem/src/ServiceMain.cs:line 20
at CommandLine.ParserResultExtensions.WithParsed[T](ParserResult`1 result, Action`1 action)
at Flexgent.Services.CryptoSubsystem.CryptoSubsystemMain.Main(String[] args) in /home/plobacz/workspace/crypto-subsystem/flexgent/extensions/security/crypto-subsystem/src/ServiceMain.cs:line 19
I suspect that this happens, because the key in SafeEvpPKeyHandle isn't private. But when i cal this:
pkcs11-tool --module /usr/lib/libtpm2_pkcs11.so --list-objects -l --pin 1234567890
I can see that there is private and public object:
ERROR:fapi:src/tss2-fapi/api/Fapi_List.c:221:Fapi_List_Finish() FAPI not provisioned.
ERROR:fapi:src/tss2-fapi/api/Fapi_List.c:81:Fapi_List() ErrorCode (0x00060034) Entities_List
ERROR: Listing FAPI token objects failed.
Using slot 0 with a present token (0x1)
Public Key Object; RSA 1024 bits
label: tls
ID: cd924ad983bc51ca1f15f446630901fa835f7b45
Usage: encrypt, verify, wrap
Access: local
Private Key Object; RSA
label: tls
ID: cd924ad983bc51ca1f15f446630901fa835f7b45
Usage: decrypt, sign, unwrap
Access: sensitive, always sensitive, never extractable, local
Allowed mechanisms: RSA-X-509,RSA-PKCS-OAEP,RSA-PKCS,SHA1-RSA-PKCS,SHA256-RSA-PKCS,SHA384-RSA-PKCS,SHA512-RSA-PKCS,RSA-PKCS-PSS,SHA1-RSA-PKCS-PSS,SHA256-RSA-PKCS-PSS,SHA384-RSA-PKCS-PSS,SHA512-RSA-PKCS-PSS
Maybe i'm giving some wrong parameters for retrievieng the private key from the engine?
BR
Piotr
[https://softgent.com/wp-content/uploads/2020/01/Zasob-14.png]<https://www.softgent.com>
Softgent Sp. z o.o., Budowlanych 31d, 80-298 Gdansk, POLAND
KRS: 0000674406, NIP: 9581679801, REGON: 367090912
www.softgent.com<http://www.softgent.com>
Sąd Rejonowy Gdańsk-Północ w Gdańsku, VII Wydział Gospodarczy Krajowego Rejestru Sądowego
KRS 0000674406, Kapitał zakładowy: 25 000,00 zł wpłacony w całości.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mta.openssl.org/pipermail/openssl-users/attachments/20210528/9ffb71fa/attachment-0001.html>
More information about the openssl-users
mailing list