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@xxxxxxxxxxx> w imieniu użytkownika Piotr Lobacz <piotr.lobacz@xxxxxxxxxxxx>
Wysłane: piątek, 28 maja 2021 13:10 Do: openssl-users@xxxxxxxxxxx <openssl-users@xxxxxxxxxxx> 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 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. |