<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
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:</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
static int HasNoPrivateKey(RSA* rsa)<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
 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.</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
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?</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
BR</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Piotr</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>Od:</b> openssl-users <openssl-users-bounces@openssl.org> w imieniu użytkownika Piotr Lobacz <piotr.lobacz@softgent.com><br>
<b>Wysłane:</b> piątek, 28 maja 2021 13:10<br>
<b>Do:</b> openssl-users@openssl.org <openssl-users@openssl.org><br>
<b>Temat:</b> CSR creation using pkcs11 dynamic engine</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hi all,<br>
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:<br>
<br>
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"<br>
<br>
The CSR is being generated and the output is like this:<br>
<br>
-----BEGIN CERTIFICATE REQUEST-----<br>
MIIBADCBqAIBADBGMQswCQYDVQQGEwJQTDEPMA0GA1UECAwGR2RhbnNrMQ8wDQYD<br>
VQQHDAZHZGFuc2sxFTATBgNVBAMMDHNvZnRnZW50LmNvbTBZMBMGByqGSM49AgEG<br>
CCqGSM49AwEHA0IABB7SwUzg8S+3iYNiqGPlidqwCdmuY8MV3RfKDiR5tL/I//Cn<br>
9dGCBAfxTO23gb5pygIXB/qCARYuYLiGpE+tFo+gADAKBggqhkjOPQQDAgNHADBE<br>
AiAI4kDGjeO/V3f7RWe34e00aZAubjLGuIRbxgmQosu7mQIgQDK3Nx22fJn80Cml<br>
t3EQTa6x9oC4RtibFgWCxZ36Wyo=<br>
-----END CERTIFICATE REQUEST-----<br>
<br>
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:<br>
<br>
public virtual SafeEvpPKeyHandle GetPrivKey(string label)<br>
{<br>
    string keyId = "label_" + label;<br>
    SafeEvpPKeyHandle pkey = SafeNativeMethods.ENGINE_load_private_key(engine, keyId, IntPtr.Zero, IntPtr.Zero);<br>
    if(pkey.IsInvalid)<br>
    {<br>
         throw new InvalidOperationException("engine: unable to find private key with label='{label}'");<br>
    }<br>
<br>
    return pkey;<br>
}<br>
<br>
This is being returnin me SafeEvpPKeyHandle. The problem is in calling CreateSigningRequest from System.Security.Cryptography.OpenSsl.dll. I have this method:<br>
<br>
public virtual string GetCSR(SafeEvpPKeyHandle pkey, string ext, HashAlgorithmName name)<br>
{<br>
    // FIXME: determine key type<br>
    RSA rsa = new RSAOpenSsl(pkey);<br>
<br>
    CertificateRequest req = new CertificateRequest("CN=potato", rsa, name, RSASignaturePadding.Pkcs1); // this method is only for RSA key different is for EC, DSA etc.<br>
    byte[] requestDer = req.CreateSigningRequest();<br>
    string requestPem = new string(PemEncoding.Write("CERTIFICATE REQUEST", requestDer));<br>
    return requestPem;<br>
}<br>
<br>
and i'm getting this error:<br>
<br>
Unhandled exception. Interop+Crypto+OpenSslCryptographicException: error:04075093:rsa routines:RSA_sign:value missing<br>
   at System.Security.Cryptography.RSAOpenSsl.TrySignHash(ReadOnlySpan`1 hash, Span`1 destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, Boolean allocateSignature, Int32& bytesWritten, Byte[]& signature)<br>
   at System.Security.Cryptography.RSAOpenSsl.SignHash(Byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)<br>
   at System.Security.Cryptography.RSA.SignData(Byte[] data, Int32 offset, Int32 count, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)<br>
   at System.Security.Cryptography.RSA.SignData(Byte[] data, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)<br>
   at System.Security.Cryptography.X509Certificates.RSAPkcs1X509SignatureGenerator.SignData(Byte[] data, HashAlgorithmName hashAlgorithm)<br>
   at System.Security.Cryptography.X509Certificates.Pkcs10CertificationRequestInfo.ToPkcs10Request(X509SignatureGenerator signatureGenerator, HashAlgorithmName hashAlgorithm)<br>
   at System.Security.Cryptography.X509Certificates.CertificateRequest.CreateSigningRequest(X509SignatureGenerator signatureGenerator)<br>
   at System.Security.Cryptography.X509Certificates.CertificateRequest.CreateSigningRequest()<br>
   at System.Security.Cryptography.Engine.GetCSR(SafeEvpPKeyHandle pkey, String ext, HashAlgorithmName name) in /home/plobacz/workspace/OpenSsl.DynamicEngine/Engine.cs:line 72<br>
   at Flexgent.Services.CryptoSubsystem.CryptoSubsystem.Configure(String config) in /home/plobacz/workspace/crypto-subsystem/flexgent/extensions/security/crypto-subsystem/src/CryptoSubsystem.cs:line 145<br>
   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<br>
   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<br>
   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<br>
   at CommandLine.ParserResultExtensions.WithParsed[T](ParserResult`1 result, Action`1 action)<br>
   at Flexgent.Services.CryptoSubsystem.CryptoSubsystemMain.Main(String[] args) in /home/plobacz/workspace/crypto-subsystem/flexgent/extensions/security/crypto-subsystem/src/ServiceMain.cs:line 19<br>
<br>
I suspect that this happens, because the key in SafeEvpPKeyHandle isn't private. But when i cal this:<br>
<br>
pkcs11-tool --module /usr/lib/libtpm2_pkcs11.so --list-objects -l --pin 1234567890<br>
<br>
I can see that there is private and public object:<br>
<br>
ERROR:fapi:src/tss2-fapi/api/Fapi_List.c:221:Fapi_List_Finish() FAPI not provisioned.<br>
ERROR:fapi:src/tss2-fapi/api/Fapi_List.c:81:Fapi_List() ErrorCode (0x00060034) Entities_List<br>
ERROR: Listing FAPI token objects failed.<br>
Using slot 0 with a present token (0x1)<br>
Public Key Object; RSA 1024 bits<br>
  label:      tls<br>
  ID:         cd924ad983bc51ca1f15f446630901fa835f7b45<br>
  Usage:      encrypt, verify, wrap<br>
  Access:     local<br>
Private Key Object; RSA<br>
  label:      tls<br>
  ID:         cd924ad983bc51ca1f15f446630901fa835f7b45<br>
  Usage:      decrypt, sign, unwrap<br>
  Access:     sensitive, always sensitive, never extractable, local<br>
  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<br>
<br>
Maybe i'm giving some wrong parameters for retrievieng the private key from the engine?<br>
<br>
BR<br>
Piotr<br>
[<a href="https://softgent.com/wp-content/uploads/2020/01/Zasob-14.png]<https://www.softgent.com">https://softgent.com/wp-content/uploads/2020/01/Zasob-14.png]<https://www.softgent.com</a>><br>
<br>
Softgent Sp. z o.o., Budowlanych 31d, 80-298 Gdansk, POLAND<br>
<br>
KRS: 0000674406, NIP: 9581679801, REGON: 367090912<br>
<br>
<a href="http://www.softgent.com">www.softgent.com</a><br>
<br>
Sąd Rejonowy Gdańsk-Północ w Gdańsku, VII Wydział Gospodarczy Krajowego Rejestru Sądowego<br>
<br>
KRS 0000674406, Kapitał zakładowy: 25 000,00 zł wpłacony w całości.<br>
</div>
</span></font></div>
</body>
</html>