I have finally figured out how to export Private Key from Fortigate firewall and successfully install Godaddy Wildcard SSL certificate in UniFi Cloud Key Gen 2 Plus Network Controller
Subject: I have finally figured out how to export Private Key from Fortigate firewall and successfully install Godaddy Wildcard SSL certificate in UniFi Cloud Key Gen 2 Plus Network Controller Good day from Singapore, Author: Mr. Turritopsis Dohrnii Teo En Ming Country: Singapore Date: 26 Oct 2022 Wednesday I have finally figured out how to export Private Key from Fortigate firewall and successfully install Godaddy Wildcard SSL certificate in UniFi Cloud Key Gen 2 Plus Network Controller because I have finally found the correct reference guides! Please refer to the following list. Reference Guides = Youtube video: Ubiquiti Networks UniFi OS SSL Certificate Installation Link: https://www.youtube.com/watch?v=WxhY71ebc9o Guide: Extracting Private Key from FortiGate Firewall Link: https://infosecmonkey.com/extracting-private-key-from-fortigate-firewall/ Guide: Extracting private key from FortiGate SSL Certificates Link: https://www.linkedin.com/pulse/extracting-private-key-from-fortigate-ssl-kuganesan-srijeyanthan Guide: How to decrypt an RSA private key and then use it in kyrtool to merge the SSL certificates. Link: https://support.hcltechsw.com/csm?id=kb_article&sysparm_article=KB0098900 Guide: How to Fix an Encrypted SSL Private Key Link: https://serverpilot.io/docs/how-to-fix-an-encrypted-ssl-private-key/ DETAILED INSTRUCTIONS FROM TEO EN MING === Login to the Fortigate 201F firewall and run the following commands using CLI. config vpn certificate local edit show full You will see something like: -BEGIN ENCRYPTED PRIVATE KEY- <---snipped---> -END ENCRYPTED PRIVATE KEY- Save the above encrypted private key as encrypted.txt in notepad or notepad++ in Windows Server. Then decrypt the encrypted private key using the openssl linux command. openssl rsa -in encrypted.txt -out plain.txt Download and install Keystore Explorer in Windows Server. Launch KeyStore Explorer 5.5.1. Click Create a new KeyStore. Click JKS. Click OK. Click Import Key Pair. Click OpenSSL. Click OK. Uncheck Encrypted Private Key. Browse OpenSSL Private Key File. (plain.txt) Browse Certificate(s) File. (chain.crt generated from Godaddy Wildcard SSL certificate) Click Import. Enter Alias: unifi Click OK. Enter New Password: aircontrolenterprise Confirm New Password: aircontrolenterprise Click OK. Click OK. Click Save. Enter New Password: aircontrolenterprise Confirm New Password: aircontrolenterprise Save KeyStore As: keystore (filename without extension) Click Save. Launch WinSCP in Windows Server. Transfer keystore file to /srv/unifi/data. Browse to /data/unifi-core/config. Create backup folder. Move default/original unifi-core.crt and unifi-core.key to above backup folder. Upload plain.txt to /data/unifi-core/config as unifi-core.key. Upload chain.crt (generated from Godaddy Wildcard SSL certificate) to /data/unifi-core/config as unifi-core.crt Reboot UniFi Cloud Key Gen 2 Plus network controller. You MUST reboot for it to take effect! SUCCESS! Browse to https://cloudkey.teo-en-ming-corp.com on your favorite web browser. You should see a padlock icon on the browser address bar. This means that the Wildcard SSL certificate was installed correctly. I started doing it at 5.00 PM and completed doing it at 6.00 PM Singapore time on 26 Oct 2022 Wednesday. Regards, Mr. Turritopsis Dohrnii Teo En Ming Targeted Individual in Singapore Blogs: https://tdtemcerts.blogspot.com https://tdtemcerts.wordpress.com
Re: RSA private key file created with Windows10
On Wed, 2022-10-05 at 16:35 +0900, Imazu Setsuo wrote: > Thank you immediately answer. > > PKCS8, PEM, and RFC4716 formats were created and tested with the ssh- > keygen command. > > PKCS8 and PEM formatting was successful. > > RFC4716 is the default on Windows10, and PEM is the default on > CentOS7. > > Does OpenSSL have any plans to support RFC4716 format in the future? No plans for that currently. Although OpenSSL-3.0 allows to plug in decoders in a separate provider so a third party support via a provider would be possible. > best regards, thank you > Setsuo Imazu > > On 2022/10/05 15:36, Tomas Mraz wrote: > > Hello, > > most probably the key is stored in the OpenSSH private key format. > > You'll need to use ssh-keygen -p -m PKCS8 to convert the key into a > > format that OpenSSL can read. > > > > Tomas Mraz, OpenSSL > > > > On Wed, 2022-10-05 at 15:00 +0900, Imazu Setsuo wrote: > > > Hello. > > > > > > When I read the RSA private key file created with the ssh-keygen > > > command that comes with Windows 10 with the PEM_read_PrivateKey() > > > function, the following error occurred. > > > > > > error: 0906D06C: lib(9): func(109): reason(108) > > > > > > The platform is CentOS7, OpenSSL 3.0.5. > > > Is the private key file created with Windows 10 not supported? > > > How can I use the private key file created in Windows 10 as well? > > > > > > > > > best regards, thank you > > > Setsuo Imazu > > -- Tomáš Mráz, OpenSSL
Re: RSA private key file created with Windows10
Thank you immediately answer. PKCS8, PEM, and RFC4716 formats were created and tested with the ssh-keygen command. PKCS8 and PEM formatting was successful. RFC4716 is the default on Windows10, and PEM is the default on CentOS7. Does OpenSSL have any plans to support RFC4716 format in the future? best regards, thank you Setsuo Imazu On 2022/10/05 15:36, Tomas Mraz wrote: Hello, most probably the key is stored in the OpenSSH private key format. You'll need to use ssh-keygen -p -m PKCS8 to convert the key into a format that OpenSSL can read. Tomas Mraz, OpenSSL On Wed, 2022-10-05 at 15:00 +0900, Imazu Setsuo wrote: Hello. When I read the RSA private key file created with the ssh-keygen command that comes with Windows 10 with the PEM_read_PrivateKey() function, the following error occurred. error: 0906D06C: lib(9): func(109): reason(108) The platform is CentOS7, OpenSSL 3.0.5. Is the private key file created with Windows 10 not supported? How can I use the private key file created in Windows 10 as well? best regards, thank you Setsuo Imazu
Re: RSA private key file created with Windows10
Hello, most probably the key is stored in the OpenSSH private key format. You'll need to use ssh-keygen -p -m PKCS8 to convert the key into a format that OpenSSL can read. Tomas Mraz, OpenSSL On Wed, 2022-10-05 at 15:00 +0900, Imazu Setsuo wrote: > Hello. > > When I read the RSA private key file created with the ssh-keygen > command that comes with Windows 10 with the PEM_read_PrivateKey() > function, the following error occurred. > > error: 0906D06C: lib(9): func(109): reason(108) > > The platform is CentOS7, OpenSSL 3.0.5. > Is the private key file created with Windows 10 not supported? > How can I use the private key file created in Windows 10 as well? > > > best regards, thank you > Setsuo Imazu -- Tomáš Mráz, OpenSSL
RSA private key file created with Windows10
Hello. When I read the RSA private key file created with the ssh-keygen command that comes with Windows 10 with the PEM_read_PrivateKey() function, the following error occurred. error: 0906D06C: lib(9): func(109): reason(108) The platform is CentOS7, OpenSSL 3.0.5. Is the private key file created with Windows 10 not supported? How can I use the private key file created in Windows 10 as well? best regards, thank you Setsuo Imazu
RE: Best Practices for private key files handling
> From: openssl-users On Behalf Of Michael > Ströder via openssl-users > Sent: Sunday, 18 September, 2022 04:27 > > On 9/18/22 06:09, Philip Prindeville wrote: > >> On Sep 15, 2022, at 4:27 PM, Michael Wojcik via openssl-users us...@openssl.org> wrote: > >> You still haven't explained your threat model, or what mitigation > >> the application can take if this requirement is violated, or why > >> you think this is a "best practice". > > > The threat model is impersonation, where the legitimate key has been > > replaced by someone else's key, and the ensuing communication is > > neither authentic nor private. > > Maybe I'm ignorant but shouldn't this be prevented by ensuring the > authenticity and correct identity mapping of the public key? Exactly. In most protocols the public key, not the private key, authenticates the peer. Relying on file system metadata (!) as the root of trust for authentication, particularly for an application that may be running with elevated privileges (!!), seems a marvelously poor design. > > Otherwise, the owners of the system can't claim non-repudiation as to > > the genuine provenance of communication. I'm with Peter Gutmann on this. Non-repudiation is essentially meaningless for the vast majority of applications. But in any case, filesystem metadata is a poor foundation for it. > More information is needed about how you're system is working to comment > on this. Indeed. This is far from clear here. -- Michael Wojcik
Re: Best Practices for private key files handling
On 9/18/22 06:09, Philip Prindeville wrote: On Sep 15, 2022, at 4:27 PM, Michael Wojcik via openssl-users wrote: You still haven't explained your threat model, or what mitigation the application can take if this requirement is violated, or why you think this is a "best practice". > The threat model is impersonation, where the legitimate key has been replaced by someone else's key, and the ensuing communication is neither authentic nor private. Maybe I'm ignorant but shouldn't this be prevented by ensuring the authenticity and correct identity mapping of the public key? More information is needed about how you're system is working to comment on this. Ciao, Michael.
Re: Best Practices for private key files handling
> On Sep 15, 2022, at 4:27 PM, Michael Wojcik via openssl-users > wrote: > >> From: openssl-users On Behalf Of Philip >> Prindeville >> Sent: Thursday, 15 September, 2022 15:41 > >> I was thinking of the case where the directory containing the keys (as >> configured) is correctly owned, but contains a symlink pointing outside of >> that directory somewhere else... say to a file owned by an ordinary user. >> >> In that case, as has been pointed out, it might be sufficient to just pay >> attention to the owner/group/modes of the file and reject them if: >> >> (1) the file isn't 600 or 400; >> (2) the file isn't owned by root or the app-id that the app runs at. > > #2 is irrelevant if #1 holds and the application isn't running as root. And > if the application doesn't need to run with elevated privileges, it shouldn't > be run with elevated privileges. > > You still haven't explained your threat model, or what mitigation the > application can take if this requirement is violated, or why you think this > is a "best practice". > > It's true there's potentially some benefit to warning an administrator even > after the fact if some violation of key hygiene is detected, but whether > that's a "best practice" (and, for that matter, the extent to which file > permissions constitute evidence of such a violation), much less whether an > application should fail in some manner when it's detected, is certainly > debatable. > The threat model is impersonation, where the legitimate key has been replaced by someone else's key, and the ensuing communication is neither authentic nor private. The application should refuse to run if it's not finding a valid, sufficiently protected key. Otherwise, the owners of the system can't claim non-repudiation as to the genuine provenance of communication. -Philip
RE: Best Practices for private key files handling
> From: openssl-users On Behalf Of Philip > Prindeville > Sent: Thursday, 15 September, 2022 15:41 > I was thinking of the case where the directory containing the keys (as > configured) is correctly owned, but contains a symlink pointing outside of > that directory somewhere else... say to a file owned by an ordinary user. > > In that case, as has been pointed out, it might be sufficient to just pay > attention to the owner/group/modes of the file and reject them if: > > (1) the file isn't 600 or 400; > (2) the file isn't owned by root or the app-id that the app runs at. #2 is irrelevant if #1 holds and the application isn't running as root. And if the application doesn't need to run with elevated privileges, it shouldn't be run with elevated privileges. You still haven't explained your threat model, or what mitigation the application can take if this requirement is violated, or why you think this is a "best practice". It's true there's potentially some benefit to warning an administrator even after the fact if some violation of key hygiene is detected, but whether that's a "best practice" (and, for that matter, the extent to which file permissions constitute evidence of such a violation), much less whether an application should fail in some manner when it's detected, is certainly debatable. -- Michael Wojcik
Re: Best Practices for private key files handling
On 9/15/2022 3:15 PM, Shawn Heisey via openssl-users wrote: If symlinks are used responsibly, they won't have security risks. In general, if the program checks the ownership and permissions of the actual file before using it, it shouldn't matter whether there is a symlink or not. As long as by "before using it" you mean after opening it and checking via fstat(). Otherwise you have a race between your check and open().
Re: Best Practices for private key files handling
On 9/15/22 15:40, Philip Prindeville wrote: I was thinking of the case where the directory containing the keys (as configured) is correctly owned, but contains a symlink pointing outside of that directory somewhere else... say to a file owned by an ordinary user. In that case, as has been pointed out, it might be sufficient to just pay attention to the owner/group/modes of the file and reject them if: (1) the file isn't 600 or 400; (2) the file isn't owned by root or the app-id that the app runs at. Do we agree on that? Yes, that sounds very good. That's the potential problem with symlinks. Rarely should they ever point to something that is under the control of an unprivileged user. Exceptions might be in cases where you actually do want a configuration for that user to come from a directory that they control ... but that should only be done in situations where that input is considered untrusted and is stringently validated and sanitized before it is used. If symlinks are used responsibly, they won't have security risks. In general, if the program checks the ownership and permissions of the actual file before using it, it shouldn't matter whether there is a symlink or not. Thanks, Shawn
Re: Best Practices for private key files handling
> On Sep 13, 2022, at 8:10 PM, Shawn Heisey via openssl-users > wrote: > > On 9/13/22 14:17, Philip Prindeville wrote: >> But what happens when the file we encounter is a symlink? If the symlink is >> owned by root but the target isn't, or the target permissions aren't 0600 0r >> 0400... Or the target is a symlink, or there's a symlink somewhere in the >> target path, etc. >> >> So... what's the Best Practices list for handling private key materials? >> Has anyone fleshed this out? > > This is not really related to openssl, but I will tell you what you are > likely to hear in another setting: > > In most cases, applications are not really aware of symlinks, unless they > have been explicitly written to treat them differently than regular files or > directories. Some software can choose to not follow symlinks, but usually > when that is possible, the program has a configuration option to > enable/disable that functionality. > > All symlinks I have ever seen on POSIX systems have 777 permissions, and MOST > of the symlinks I have seen have root:root ownership. I've never seen a > situation where the ownership of the link itself has any bearing on whether > the target location can be accessed. I'm not going to unilaterally claim > that isn't possible, but I have never seen it. > > Best practices do not change when there are symlinks involved, unless the > software refuses to follow symlinks. Anything that would apply to a real > file/directory would apply to the target of a symlink. My own best practices > about private keys: They should only be readable by root and whatever > user/group is active when software needs to use them. They should definitely > not be writable by any user other than root. Some software starts as root to > handle security stuff, then throws away the elevated permissions and runs as > an unprivileged user. Apache httpd is a prime example of this. > > You might be concerned that with 777 permissions, a symlink can be modified > by anyone ... but I am about 98 percent sure that is not the case when proper > permissions are used. I believe that a symlink can only be modified by a > user that has write permission to the directory containing the symlink. > > Properly implemented, symlinks do not reduce security, but any tool can be > misused. If you have a situation where a symlink presents a security > concern, it probably means someone did it wrong. > > Thanks, > Shawn > I was thinking of the case where the directory containing the keys (as configured) is correctly owned, but contains a symlink pointing outside of that directory somewhere else... say to a file owned by an ordinary user. In that case, as has been pointed out, it might be sufficient to just pay attention to the owner/group/modes of the file and reject them if: (1) the file isn't 600 or 400; (2) the file isn't owned by root or the app-id that the app runs at. Do we agree on that? -Philip
Re: Best Practices for private key files handling
On 9/13/22 14:17, Philip Prindeville wrote: But what happens when the file we encounter is a symlink? If the symlink is owned by root but the target isn't, or the target permissions aren't 0600 0r 0400... Or the target is a symlink, or there's a symlink somewhere in the target path, etc. So... what's the Best Practices list for handling private key materials? Has anyone fleshed this out? This is not really related to openssl, but I will tell you what you are likely to hear in another setting: In most cases, applications are not really aware of symlinks, unless they have been explicitly written to treat them differently than regular files or directories. Some software can choose to not follow symlinks, but usually when that is possible, the program has a configuration option to enable/disable that functionality. All symlinks I have ever seen on POSIX systems have 777 permissions, and MOST of the symlinks I have seen have root:root ownership. I've never seen a situation where the ownership of the link itself has any bearing on whether the target location can be accessed. I'm not going to unilaterally claim that isn't possible, but I have never seen it. Best practices do not change when there are symlinks involved, unless the software refuses to follow symlinks. Anything that would apply to a real file/directory would apply to the target of a symlink. My own best practices about private keys: They should only be readable by root and whatever user/group is active when software needs to use them. They should definitely not be writable by any user other than root. Some software starts as root to handle security stuff, then throws away the elevated permissions and runs as an unprivileged user. Apache httpd is a prime example of this. You might be concerned that with 777 permissions, a symlink can be modified by anyone ... but I am about 98 percent sure that is not the case when proper permissions are used. I believe that a symlink can only be modified by a user that has write permission to the directory containing the symlink. Properly implemented, symlinks do not reduce security, but any tool can be misused. If you have a situation where a symlink presents a security concern, it probably means someone did it wrong. Thanks, Shawn
RE: Best Practices for private key files handling
> From: openssl-users On Behalf Of Philip > Prindeville > Sent: Tuesday, 13 September, 2022 14:17 > > I'm working on a bug in an application where the application config is given > the directory path in which to find a key-store, which it then loads. > > My issue is this: a regular UNIX file is trivial to handle (make sure it's > owned by "root" or the uid that the app runs at, and that it's 0600 or 0400 > permissions... easy-peasy). > > But what happens when the file we encounter is a symlink? You read the target. What's the problem? > If the symlink is > owned by root but the target isn't, or the target permissions aren't 0600 0r > 0400... So what? You can use lstat if you're really worried about symlinks, but frankly I'm not seeing the vulnerability, at least at first blush. What's the threat model? This is reading a private key, not writing one, so there's no exfiltration issue simply from reading the file. Suppose an attacker replaces the private key file, or the contents of the file. So what? Either the attacker is in a privileged position and so can satisfy your ownership and permissions checks; or the attacker isn't, and ... you read a private key that either is the correct one (i.e. corresponds to the public key in the certificate), and so there's no problem; or it isn't, and you can't use the certificate, and you fail safe. Is this check meant to alert an administrator to a possibly-compromised, or prone-to-compromise, private key? Because if so, 1) it's too late, 2) a privileged attacker can trivially prevent it, and 3) why is that your job anyway? It's also not clear to me why symbolic links are toxic under your threat model. It's entirely possible I'm missing something here, but my initial impression is that these checks are of little value anyway. Can you explain what problem you're trying to solve? -- Michael Wojcik
Best Practices for private key files handling
Hi, I'm working on a bug in an application where the application config is given the directory path in which to find a key-store, which it then loads. My issue is this: a regular UNIX file is trivial to handle (make sure it's owned by "root" or the uid that the app runs at, and that it's 0600 or 0400 permissions... easy-peasy). But what happens when the file we encounter is a symlink? If the symlink is owned by root but the target isn't, or the target permissions aren't 0600 0r 0400... Or the target is a symlink, or there's a symlink somewhere in the target path, etc. So... what's the Best Practices list for handling private key materials? Has anyone fleshed this out? The specific bug, if anyone is interested, is: https://issues.asterisk.org/jira/browse/ASTERISK-30213 Thanks, -Philip
Re: Is there a simple implementation of hooking external private key with openssl-3.0 API?
On 11/04/2022 16:53, Alon Bar-Lev wrote: On Mon, Apr 11, 2022 at 11:52 AM Matt Caswell wrote: On 10/04/2022 19:18, Alon Bar-Lev wrote: Hello, I am trying to migrate to openssl-3.0 API, it seems to be very complicated to hook primitive private key usage to a custom function. This is required, for example, to use private keys that reside on hardware devices or when an application wishes to externalize private key operations to other programs using IPC. I hope I am wrong but it seems like an entirely new provider must be implemented with complete reimplementation of the default providers, including serialization, padding etc... While in openssl-0/1 it was quite easy. You will need to implement a provider, and include a key manager plus an implementation of whatever operations you want to support, e.g. signature or asymcipher. Typically where a private key resides on a hardware device then you don't need to support serialization/deserialization because the keys can't be serialized/deserialized anyway. If you do want to support that then the key manager just needs to be able to import or export keys using the standard parameters for the algorithm and it will automatically be able to use the default provider's encoders and decoders. Support for key generation is also probably optional. You would need to support any padding that you need - that's considered part of the low level algorithm implementation. Thank you Matt, I am aware I can implement new three providers from scratch. However, I was hopping you will show me a way to cascade the existing providers just like we have done in the past with the RSA_METHOD. It is actually technically possible to cascade providers. There is an example of this happening in the test code. We have a filter provider which "wraps" the default provider and modifies its behaviour. See: https://github.com/openssl/openssl/blob/master/test/filterprov.c However, I'm not sure that it helps you in this particular instance. We also have instances of "composite" algorithms, e.g. where a high level algorithm makes use of some other low level algorithm (consider a DigestSign operation which uses RSA for signing, but also uses some digest algorithm as part of its work). I would like the exact behavior of the existing providers while overriding the low level RSA operations. The problem is that we don't currently expose the low level RSA operations as provider operations. Feasibly we could have two RSA implementations - a "low" level one and a "high" level one, where the high level one does all padding etc, and the "low" level one does the actual raw RSA work. The high level one could then call the low level one. If we had that then it would probably be feasible for you to hook in an alternative implementation for just the low level pieces. That would require some refactoring though. Are you opened for a discussion for improving this? Absolutely. I'd suggest you raise an issue on github to discuss it. I'm sure someone else raised a similar issue some while ago and we had some similar discussions, but I've gone searching for it and couldn't find it. I did come across this issue though which touches on some similar topics: https://github.com/openssl/openssl/issues/17187 Matt [1] https://github.com/OpenVPN/openvpn/blob/master/src/openvpn/xkey_provider.c [2] https://github.com/OpenVPN/openvpn/blob/master/src/openvpn/xkey_helper.c I wrote a testcase program using openssl-1 APIs[1] which also works using openssl-3, in this testcase I prepare a new RSA method based on the default method, hook the private operations and then hook the RSA object to use the custom method. I am looking for a way to implement the __hook_evp_pkey function in openssl-3 api, so that when a private key operation is executed on the EVP_PKEY or EVP_PKEY_CTX a custom callback will be executed while public key operation continue to be executed normally. While looking into the existing RSA providers I can see that the providers continue to use the deprecated RSA_* functions with the following comment: /* * RSA low level APIs are deprecated for public use, but still ok for * internal use. */ This is exactly what I need... :) To have the RSA low level API be redirected back to the application so that I can enjoy the default implementation of signature/rsa_sig.c padding etc while being able to override the private encrypt. But these low level functions are hidden from the user. As the comment says, RSA low level APIs are deprecated. Deprecated does *not* mean removed. So you can still use them for now, although expect them to be removed from some future version of OpenSSL. Marking deprecated APIs is announcing your intentions and gives enough time for everyone to workout the gaps (if any). I believe there is a gap which will introduce
Re: Is there a simple implementation of hooking external private key with openssl-3.0 API?
On Mon, Apr 11, 2022 at 11:52 AM Matt Caswell wrote: > > > > On 10/04/2022 19:18, Alon Bar-Lev wrote: > > Hello, > > > > I am trying to migrate to openssl-3.0 API, it seems to be very > > complicated to hook primitive private key usage to a custom function. > > This is required, for example, to use private keys that reside on > > hardware devices or when an application wishes to externalize private > > key operations to other programs using IPC. > > > > I hope I am wrong but it seems like an entirely new provider must be > > implemented with complete reimplementation of the default providers, > > including serialization, padding etc... While in openssl-0/1 it was > > quite easy. > > > > You will need to implement a provider, and include a key manager plus an > implementation of whatever operations you want to support, e.g. > signature or asymcipher. Typically where a private key resides on a > hardware device then you don't need to support > serialization/deserialization because the keys can't be > serialized/deserialized anyway. If you do want to support that then the > key manager just needs to be able to import or export keys using the > standard parameters for the algorithm and it will automatically be able > to use the default provider's encoders and decoders. Support for key > generation is also probably optional. You would need to support any > padding that you need - that's considered part of the low level > algorithm implementation. > Thank you Matt, I am aware I can implement new three providers from scratch. However, I was hopping you will show me a way to cascade the existing providers just like we have done in the past with the RSA_METHOD. I would like the exact behavior of the existing providers while overriding the low level RSA operations. Even if I would implement an entirely new provider I guess I need to keep using deprecated low level RSA_* functions for the public key part. OpenVPN had brute forced this[1][2] in about 1500 lines of code of what used to be about 120 lines of code. I would like to raise my concern that this openssl-3.0 provider interface may need some improvement to allow easier integration, similar to what we had in openssl since about ever. Are you opened for a discussion for improving this? [1] https://github.com/OpenVPN/openvpn/blob/master/src/openvpn/xkey_provider.c [2] https://github.com/OpenVPN/openvpn/blob/master/src/openvpn/xkey_helper.c > > > I wrote a testcase program using openssl-1 APIs[1] which also works > > using openssl-3, in this testcase I prepare a new RSA method based on > > the default method, hook the private operations and then hook the RSA > > object to use the custom method. > > > > I am looking for a way to implement the __hook_evp_pkey function in > > openssl-3 api, so that when a private key operation is executed on the > > EVP_PKEY or EVP_PKEY_CTX a custom callback will be executed while > > public key operation continue to be executed normally. > > > > While looking into the existing RSA providers I can see that the > > providers continue to use the deprecated RSA_* functions with the > > following comment: > > > > /* > > * RSA low level APIs are deprecated for public use, but still ok for > > * internal use. > > */ > > > > This is exactly what I need... :) To have the RSA low level API be > > redirected back to the application so that I can enjoy the default > > implementation of signature/rsa_sig.c padding etc while being able to > > override the private encrypt. But these low level functions are hidden > > from the user. > > As the comment says, RSA low level APIs are deprecated. Deprecated does > *not* mean removed. So you can still use them for now, although expect > them to be removed from some future version of OpenSSL. Marking deprecated APIs is announcing your intentions and gives enough time for everyone to workout the gaps (if any). I believe there is a gap which will introduce a great burden for developers in the existing design, I would like to work with you to reach similar solution we had in prior openssl versions by leveraging the current provider approach and create a reference implementation similar to what I've provided. If I understand the design correctly the missing bits are the ability to cascade a provider and access low level primitives, maybe as its own provider. > Matt > Thanks, Alon > > > > Can anyone help us to create a testcase of openssl-3? This will help > > many applications such as opensc/libp11 opensc/pkcs11-helper openvpn > > and probably more. > > > > For your convenience, you may find the program here[1]. > >
Re: Is there a simple implementation of hooking external private key with openssl-3.0 API?
On 10/04/2022 19:18, Alon Bar-Lev wrote: Hello, I am trying to migrate to openssl-3.0 API, it seems to be very complicated to hook primitive private key usage to a custom function. This is required, for example, to use private keys that reside on hardware devices or when an application wishes to externalize private key operations to other programs using IPC. I hope I am wrong but it seems like an entirely new provider must be implemented with complete reimplementation of the default providers, including serialization, padding etc... While in openssl-0/1 it was quite easy. You will need to implement a provider, and include a key manager plus an implementation of whatever operations you want to support, e.g. signature or asymcipher. Typically where a private key resides on a hardware device then you don't need to support serialization/deserialization because the keys can't be serialized/deserialized anyway. If you do want to support that then the key manager just needs to be able to import or export keys using the standard parameters for the algorithm and it will automatically be able to use the default provider's encoders and decoders. Support for key generation is also probably optional. You would need to support any padding that you need - that's considered part of the low level algorithm implementation. I wrote a testcase program using openssl-1 APIs[1] which also works using openssl-3, in this testcase I prepare a new RSA method based on the default method, hook the private operations and then hook the RSA object to use the custom method. I am looking for a way to implement the __hook_evp_pkey function in openssl-3 api, so that when a private key operation is executed on the EVP_PKEY or EVP_PKEY_CTX a custom callback will be executed while public key operation continue to be executed normally. While looking into the existing RSA providers I can see that the providers continue to use the deprecated RSA_* functions with the following comment: /* * RSA low level APIs are deprecated for public use, but still ok for * internal use. */ This is exactly what I need... :) To have the RSA low level API be redirected back to the application so that I can enjoy the default implementation of signature/rsa_sig.c padding etc while being able to override the private encrypt. But these low level functions are hidden from the user. As the comment says, RSA low level APIs are deprecated. Deprecated does *not* mean removed. So you can still use them for now, although expect them to be removed from some future version of OpenSSL. Matt Can anyone help us to create a testcase of openssl-3? This will help many applications such as opensc/libp11 opensc/pkcs11-helper openvpn and probably more. For your convenience, you may find the program here[1]. Regards, Alon Bar-Lev [1] https://github.com/alonbl/openssl-external/blob/master/example.c --- #include #include #include #include #include #include static RSA_METHOD *__example_rsa_method; static int __example_rsa_index; static int __example_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { const RSA_METHOD *rsa_method = NULL; int ret = -1; if ((rsa_method = RSA_get_method(rsa)) == NULL) { goto cleanup; } /* * Do it. */ printf("ENCRYPT\n"); memset(to, 0, flen); ret = 1; cleanup: return ret; } static int __example_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { const RSA_METHOD *rsa_method = NULL; int ret = -1; if ((rsa_method = RSA_get_method(rsa)) == NULL) { goto cleanup; } /* * Do it. */ printf("DECRYPT\n"); memset(to, 0, flen); ret = 1; cleanup: return ret; } static int __prepare_method(void) { int ret = 0; if ((__example_rsa_method = RSA_meth_dup(RSA_get_default_method())) == NULL) { goto cleanup; } if (!RSA_meth_set1_name(__example_rsa_method, "example")) { goto cleanup; } if (!RSA_meth_set_priv_dec(__example_rsa_method, __example_rsa_priv_dec)) { goto cleanup; } if (!RSA_meth_set_priv_enc(__example_rsa_method, __example_rsa_priv_enc)) { goto cleanup; } if ((__example_rsa_index = RSA_get_ex_new_index(0, "example", NULL, NULL, NULL)) == -1) { goto cleanup; } ret = 1; cleanup: return ret; } static int __free_method(void) { RSA_meth_free(__example_rsa_method); } static int __hook_evp_pkey(EVP_PKEY *evp_pkey) { RSA *rsa = NULL; int ret = 0; /* * Hook private key methods */ if (EVP_PKEY_id(evp_pkey) != EVP_PKEY_RSA) { goto cleanup; } if ((rsa = EVP_PKEY_get1_RSA(evp_pkey)) == NULL) { goto cleanup
Is there a simple implementation of hooking external private key with openssl-3.0 API?
Hello, I am trying to migrate to openssl-3.0 API, it seems to be very complicated to hook primitive private key usage to a custom function. This is required, for example, to use private keys that reside on hardware devices or when an application wishes to externalize private key operations to other programs using IPC. I hope I am wrong but it seems like an entirely new provider must be implemented with complete reimplementation of the default providers, including serialization, padding etc... While in openssl-0/1 it was quite easy. I wrote a testcase program using openssl-1 APIs[1] which also works using openssl-3, in this testcase I prepare a new RSA method based on the default method, hook the private operations and then hook the RSA object to use the custom method. I am looking for a way to implement the __hook_evp_pkey function in openssl-3 api, so that when a private key operation is executed on the EVP_PKEY or EVP_PKEY_CTX a custom callback will be executed while public key operation continue to be executed normally. While looking into the existing RSA providers I can see that the providers continue to use the deprecated RSA_* functions with the following comment: /* * RSA low level APIs are deprecated for public use, but still ok for * internal use. */ This is exactly what I need... :) To have the RSA low level API be redirected back to the application so that I can enjoy the default implementation of signature/rsa_sig.c padding etc while being able to override the private encrypt. But these low level functions are hidden from the user. Can anyone help us to create a testcase of openssl-3? This will help many applications such as opensc/libp11 opensc/pkcs11-helper openvpn and probably more. For your convenience, you may find the program here[1]. Regards, Alon Bar-Lev [1] https://github.com/alonbl/openssl-external/blob/master/example.c --- #include #include #include #include #include #include static RSA_METHOD *__example_rsa_method; static int __example_rsa_index; static int __example_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { const RSA_METHOD *rsa_method = NULL; int ret = -1; if ((rsa_method = RSA_get_method(rsa)) == NULL) { goto cleanup; } /* * Do it. */ printf("ENCRYPT\n"); memset(to, 0, flen); ret = 1; cleanup: return ret; } static int __example_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { const RSA_METHOD *rsa_method = NULL; int ret = -1; if ((rsa_method = RSA_get_method(rsa)) == NULL) { goto cleanup; } /* * Do it. */ printf("DECRYPT\n"); memset(to, 0, flen); ret = 1; cleanup: return ret; } static int __prepare_method(void) { int ret = 0; if ((__example_rsa_method = RSA_meth_dup(RSA_get_default_method())) == NULL) { goto cleanup; } if (!RSA_meth_set1_name(__example_rsa_method, "example")) { goto cleanup; } if (!RSA_meth_set_priv_dec(__example_rsa_method, __example_rsa_priv_dec)) { goto cleanup; } if (!RSA_meth_set_priv_enc(__example_rsa_method, __example_rsa_priv_enc)) { goto cleanup; } if ((__example_rsa_index = RSA_get_ex_new_index(0, "example", NULL, NULL, NULL)) == -1) { goto cleanup; } ret = 1; cleanup: return ret; } static int __free_method(void) { RSA_meth_free(__example_rsa_method); } static int __hook_evp_pkey(EVP_PKEY *evp_pkey) { RSA *rsa = NULL; int ret = 0; /* * Hook private key methods */ if (EVP_PKEY_id(evp_pkey) != EVP_PKEY_RSA) { goto cleanup; } if ((rsa = EVP_PKEY_get1_RSA(evp_pkey)) == NULL) { goto cleanup; } if (!RSA_set_method(rsa, __example_rsa_method)) { goto cleanup; } if (!RSA_set_ex_data(rsa, __example_rsa_index, "mystate")) { goto cleanup; } if (EVP_PKEY_set1_RSA(evp_pkey, rsa) != 1) { goto cleanup; } ret = 1; cleanup: RSA_free(rsa); return ret; } const static char *pem = ( "-BEGIN CERTIFICATE-\n" "MIIFMDCCBBigAwIBAgISA6sbShb1HQ3TpSVvhSPOS4JJMA0GCSqGSIb3DQEBCwUA\n" "MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD\n" "EwJSMzAeFw0yMjAzMTAxNzQ4MDdaFw0yMjA2MDgxNzQ4MDZaMBoxGDAWBgNVBAMT\n" "D210YS5vcGVuc3NsLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n" "AMZvA0BbvdyVc+06j5e5k6dUr8gqL0KZw0w4xJ0QD6jD/o+czNEMz13YDxuZ5utL\n" "YGq8uohlK8l2DWqvDfGfm1T4VYQhD2z0Ky0JDTsxDIb5i6kKA+o2j2VPAivfMkBp\n" "f47rLITa4vqZ8/aro3E0ZVWfbpOOGASteM/g9mLEpRLJQA2/o4uu9xLCsyJkLG8F\n" "8eTCHUJ8388ZO/3fv8LnN1+/WwciSYcZcZNN44OsrgLNoLh6dzSY+oNZyVGdqxUy\n"
Re: Fwd: Trying to generate a RSA private key
Hi Victor, Thanks for advising me and for the links. I'm learning a lot, despite the bad news Thanks. Kind regards loredana Il giorno mer 16 feb 2022 alle ore 15:30 Viktor Dukhovni < openssl-us...@dukhovni.org> ha scritto: > On Wed, Feb 16, 2022 at 11:16:03AM +0100, mary mary wrote: > > > But now the issue would become different, and I'll try to share it > > possibly even if the subject changes, in case i could get advice. I > > needed the private key for adding it in wireshark for decoding some > > encrypted messages exchanged between "my" server and a client. If the > > private key does not exist, how we could decode the messages? > > Well, now that we're past the XY problem, there's good news and bad > news. > > Good news: > > * If you control the server, the server's private key is typically > stored in the server's private key file (possible same as its > certificate file). If the server is OpenSSL rather than Java > based, it would typically already be in PEM format, ... > > Bad news: > > * Even with the server's private key, you generally can't decrypt TLS > traffic, when, as is typical and best-practice, the negotiated > cipher has forward-secrecy (uses DH or ECDH key exchange). > > To actually decode the traffic, you'd need to configure the server or > client to record the session "master secret". A client-side example > is discussed in: > > > https://resources.infosecinstitute.com/topic/decrypting-ssl-tls-traffic-with-wireshark/ > > Alternatively, In the blog post at: > > > https://blog.didierstevens.com/2020/12/14/decrypting-tls-streams-with-wireshark-part-1/ > > there's an example which downgrades the client TLS parameters to use at > most TLS 1.2 and RSA key transport (instead of DH), which then makes it > it possible to use the server's private key to decrypt the traffic. > > -- > Viktor. >
Re: Fwd: Trying to generate a RSA private key
On Wed, Feb 16, 2022 at 11:16:03AM +0100, mary mary wrote: > But now the issue would become different, and I'll try to share it > possibly even if the subject changes, in case i could get advice. I > needed the private key for adding it in wireshark for decoding some > encrypted messages exchanged between "my" server and a client. If the > private key does not exist, how we could decode the messages? Well, now that we're past the XY problem, there's good news and bad news. Good news: * If you control the server, the server's private key is typically stored in the server's private key file (possible same as its certificate file). If the server is OpenSSL rather than Java based, it would typically already be in PEM format, ... Bad news: * Even with the server's private key, you generally can't decrypt TLS traffic, when, as is typical and best-practice, the negotiated cipher has forward-secrecy (uses DH or ECDH key exchange). To actually decode the traffic, you'd need to configure the server or client to record the session "master secret". A client-side example is discussed in: https://resources.infosecinstitute.com/topic/decrypting-ssl-tls-traffic-with-wireshark/ Alternatively, In the blog post at: https://blog.didierstevens.com/2020/12/14/decrypting-tls-streams-with-wireshark-part-1/ there's an example which downgrades the client TLS parameters to use at most TLS 1.2 and RSA key transport (instead of DH), which then makes it it possible to use the server's private key to decrypt the traffic. -- Viktor.
Re: Fwd: Trying to generate a RSA private key
Hello Mark, Thank you so much for your input. Indeed there is not an entry for the private key, and that let me understand why i could not extract it. But now the issue would become different, and I'll try to share it possibly even if the subject changes, in case i could get advice. I needed the private key for adding it in wireshark for decoding some encrypted messages exchanged between "my" server and a client. If the private key does not exist, how we could decode the messages? Thank You!. Kind regards loredana Il giorno mar 15 feb 2022 alle ore 20:30 Mark Hack ha scritto: > > Use keytool -list -v to ensure that the original store actually contains a > private key > > If there is no entry of *Entry type: PrivateKeyEntry* then the store has > no private key > > > Mark Hack > > > On Tue, 2022-02-15 at 18:30 +0100, mary mary wrote:Hello community, > > A beginner here. > > I would need to extract a private key, PEM or RSA format, from a keystore > file ("server.keystore") which I have. > I've executed: > > keytool -importkeystore -srcstorepass 123456 -srckeystore server.keystore > -deststorepass 123456 -destkeystore server.p12 -deststoretype PKCS12 > > openssl pkcs12 -in server.p12 -passin pass:123456 -out server-key-temp.pem > -nodes -nocerts > > But i get an empty file: server-key-temp.pem is empty. > > What's wrong? > > Thank You. > > Kind regards > > >
Re: Fwd: Trying to generate a RSA private key
Use keytool -list -v to ensure that the original store actually contains a private key If there is no entry of Entry type: PrivateKeyEntry then the store has no private key Mark Hack On Tue, 2022-02-15 at 18:30 +0100, mary mary wrote:Hello community, > A beginner here. > > I would need to extract a private key, PEM or RSA format, from a > keystore file ("server.keystore") which I have. > I've executed: > > keytool -importkeystore -srcstorepass 123456 -srckeystore > server.keystore -deststorepass 123456 -destkeystore server.p12 > -deststoretype PKCS12 > > openssl pkcs12 -in server.p12 -passin pass:123456 -out server-key- > temp.pem -nodes -nocerts > > But i get an empty file: server-key-temp.pem is empty. > > What's wrong? > > Thank You. > > Kind regards > > > >
Fwd: Trying to generate a RSA private key
Hello community, A beginner here. I would need to extract a private key, PEM or RSA format, from a keystore file ("server.keystore") which I have. I've executed: keytool -importkeystore -srcstorepass 123456 -srckeystore server.keystore -deststorepass 123456 -destkeystore server.p12 -deststoretype PKCS12 openssl pkcs12 -in server.p12 -passin pass:123456 -out server-key-temp.pem -nodes -nocerts But i get an empty file: server-key-temp.pem is empty. What's wrong? Thank You. Kind regards
[Mostly off-topic] Build RSA private key from (p,q,e) triple
Every once in a while IIRC there are posts asking about how to create an RSA private key from the two prime factors (p and q) and exponent. Though there are surely simple examples in Python or Perl, I happened to write on in Haskell. Here it is for posterity (Main.hs and .cabal spec). Input is from stdin, with each of p, q and e in either decimal or 0x-prefixed hex on separate lines. 10 lines of boilerplate and 3 lines of code: --- Main.hs: module Main (main) where import qualified Data.ByteString as B import Crypto.Number.Basic (numBytes) import Crypto.PubKey.RSA (generateWith) import Data.ASN1.BinaryEncoding (DER(DER)) import Data.ASN1.Encoding (encodeASN1') import Data.ASN1.Types (toASN1) import Data.X509 (PrivKey(PrivKeyRSA)) main :: IO () main = do (p, q, e) <- (,,) <$> readLn <*> readLn <*> readLn mapM_ (B.putStr . toDER) $ generateWith (p,q) (numBytes (p*q)) e where toDER = encodeASN1' DER . flip toASN1 [] . PrivKeyRSA . snd --- pqe.cabal: cabal-version: 2.4 name: pqe version:0.1.0.0 executable pqe main-is: Main.hs build-depends:base >= 4.14 && < 5 , asn1-encoding ^>= 0.9 , asn1-types ^>= 0.3 , bytestring >= 0.10 && < 0.12 , cryptonite ^>= 0.29 , x509 ^>= 1.7 --- The output is legacy RSA DER, but can be converted to PKCS8 PEM by piping it to "openssl pkey -inform DER" (optionally adding a passphrase, ...): If the program fails to read the (p, q, e) values it will exit with an error. If these fail to yield a valid key it will produce no output. Silly little example with (p, q, e) = (29, 23, 3): $ printf '%s\n%s\n%s\n' 29 23 3 | cabal run -v0 | openssl pkey -inform DER -text -BEGIN PRIVATE KEY- MDMCAQAwDQYJKoZIhvcNAQEBBQAEHzAdAgEAAgICmwIBAwICAZsCAR0CARcCARMC AQ8CARg= -END PRIVATE KEY- RSA Private-Key: (10 bit, 2 primes) modulus: 667 (0x29b) publicExponent: 3 (0x3) privateExponent: 411 (0x19b) prime1: 29 (0x1d) prime2: 23 (0x17) exponent1: 19 (0x13) exponent2: 15 (0xf) coefficient: 24 (0x18) More realistic example with a throw-away 2048-bit RSA key: $ cabal run -v0 < 0xfb9e9c8a90615c9edd4870b2eb434a76abcf8ffe22d0764fdf9c921523b561b25edd2ebc547836ab2e40ba7229e2f023dde7f2209c0d8ba548d442a7e9ee415f97714a1f6cdd53aa6e67b2d020287c4b2fe730355e04fb25f93b078bf41a7af8e6700c4cf2e2407720e19f90464d8e9cb4d70d960c23309b3228b5510e550833 > 0xe779cd8cc5a7d3ae41cfe4869598832aeec3e26b0919743486f9e5d0cf1e00826a6ffe865d347e35b0c55cfcef32515b6850d552be53b5af335c3e0a8062a5d4e063b33071365f3faac29e44990f83f2994bb93cf45a0c09a4fef13e441128ebe9c36ef2dc32dddffc99ed7d1ad7bc0232c1692ff3ee466c6bcb612074d54187 > 0x10001 > EOF -BEGIN PRIVATE KEY- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDjg9dBZiSs+s4w JZgYVNknm6TW4vh8lONdEOe6lquTYDciA53K00dededDmjwvQYMHbsoA6TyC/5O4 r8T21GaXwdQHHOsMou9JcyU+5Sun350I2lh7sDeJ0Ipz/nn3RwitXBHeWMLz1MLD Arutm0Wc1ZFC0ri2sxXTXsoYYc4mqMCBp0C8sPkQCAkheCsOBkWHaYK6vlsOXK/V O1LMaxqawYZamfPQ7Nznh3rVjVY2v/zlEtHqtNbzjMu6cJrLKgzYzhfxWMO/aNA/ QhjZoUjSNFTP5VwhpyP7EFQlrMQFLb4vumboj5G66jiHWk/SeDn5LxhLyFbnijSe ADkUW0XlAgMBAAECggEBALnNBLCrCw6dMF/Pg9tzB3i6Oi8nYsjTCq8JTEVsIKiV rdDAZU+rpaA152yk+7uX47rhNmTyFPHiaLAuE0uEgFg0+cPpUOeb9JDmUSeBHlrV WjhNoG86pNCOl1NNIivYPfTduNX9ZRCd04RQqhaINJx1KVEKJ8FElXFt+ttYnHOi WDVGtpXYNjM+6s/R6UpkSTL0SpVjY7RjQMXZ8P3uUrAru/4UQba0ZcZIbHXSQO5J MCWa05pIOGuTs0C/2nUuO+lN5fqz6Cv8G+YlQjp54MUcjK3XisP/vx9GC4uvt3XT ik8y/+plvvBk1nwO8ehJ01bUzgokWNkePI58lfczqu0CgYEA+56cipBhXJ7dSHCy 60NKdqvPj/4i0HZP35ySFSO1YbJe3S68VHg2qy5AunIp4vAj3efyIJwNi6VI1EKn 6e5BX5dxSh9s3VOqbmey0CAofEsv5zA1XgT7Jfk7B4v0Gnr45nAMTPLiQHcg4Z+Q Rk2OnLTXDZYMIzCbMii1UQ5VCDMCgYEA53nNjMWn065Bz+SGlZiDKu7D4msJGXQ0 hvnl0M8eAIJqb/6GXTR+NbDFXPzvMlFbaFDVUr5Tta8zXD4KgGKl1OBjszBxNl8/ qsKeRJkPg/KZS7k89FoMCaT+8T5EESjr6cNu8twy3d/8me19Gte8AjLBaS/z7kZs a8thIHTVQYcCgYEAw1apdLENxNfYNmq3nAkLgAF2C/VhlbCj5ZcpmZu1LnlJSDEG KBWDa3Vm7te+SN3hGl79C+/aXDUeyxpMPUGoIsvxOXgYDeLsBvYeTZEJnSTJtZMp eyomx54rA3rVMNGS9WK7SemtWBqjvkUfvlRriKCj63o3RgJwGYqc6KZVwR0CgYEA uNfNSrKz+BfZOhg1WNR3Oht8lRwAIjFnmLmJyZr7TFDYiiJoTZmTh3Bnyn+4yyeo pL6X+wE9e4Iys2BfpnIgFsQxGXB/l3msL8JF/GV1vFpIC+4aPM6DelgltaORW1qg OQX1XT516DPrVUgOdRb9bYv2YvcGBap6/gFkyDRD75UCgYAkruxwtnikj5hKlaSJ /OIXvjj3VmbPpJtSFbvadTCTzBxWCWjaBQHf0nKsbNRa/9V60y44L0EVnC40Udj6 r6LxLw66+GHJQPfhW5bnFIpUksIDC8fF9gUyc+C0AI3OJR+jrmlXNAllqoNIEsYd mkdZ2BxLEY0/fmBftSO3d/dC+A== -END PRIVATE KEY- -- Viktor.
Re: How to get rsa-private key in plain text format?
Thank you very much Regards, Shariful Alam On Fri, Sep 3, 2021 at 10:29 AM Matt Caswell wrote: > > > On 03/09/2021 17:24, Shariful Alam wrote: > > Thank you very much. > > So the output of "*openssl rsa -in mykey.pem -text -noout*" is a base64 > > hex format? > > It's a hex format. "base64 hex" makes no sense. base64 is not hex, and > vice versa. > > Matt > > > > > Regards, > > Shariful > > > > On Fri, Sep 3, 2021 at 7:55 AM Matt Caswell > <mailto:m...@openssl.org>> wrote: > > > > > > > > On 03/09/2021 14:49, Billy Brumley wrote: > > >>> Hello, > > >>> Is there any command-line tool to get the plain text rsa > > private key > > >>> like the following format from .pem file? > > >> > > >> openssl rsa -in mykey.pem -noout -text > > > > > > It would in fact be much more educational to advocate pkey, which > is > > > cryptosystem agnostic > > > > Good point! > > > > Matt > > > > > > > > openssl pkey -in mykey.pem -noout -text > > > > > > Since I would expect the rsa command to go the same was as the > rsautl > > > command in the future. > > > > > > Happy Friday! > > > > > > BBB > > > > > >
Re: How to get rsa-private key in plain text format?
> > > >
Re: How to get rsa-private key in plain text format?
On 03/09/2021 17:24, Shariful Alam wrote: Thank you very much. So the output of "*openssl rsa -in mykey.pem -text -noout*" is a base64 hex format? It's a hex format. "base64 hex" makes no sense. base64 is not hex, and vice versa. Matt Regards, Shariful On Fri, Sep 3, 2021 at 7:55 AM Matt Caswell <mailto:m...@openssl.org>> wrote: On 03/09/2021 14:49, Billy Brumley wrote: >>> Hello, >>> Is there any command-line tool to get the plain text rsa private key >>> like the following format from .pem file? >> >> openssl rsa -in mykey.pem -noout -text > > It would in fact be much more educational to advocate pkey, which is > cryptosystem agnostic Good point! Matt > > openssl pkey -in mykey.pem -noout -text > > Since I would expect the rsa command to go the same was as the rsautl > command in the future. > > Happy Friday! > > BBB >
Re: How to get rsa-private key in plain text format?
Thank you very much. So the output of "*openssl rsa -in mykey.pem -text -noout*" is a base64 hex format? Regards, Shariful On Fri, Sep 3, 2021 at 7:55 AM Matt Caswell wrote: > > > On 03/09/2021 14:49, Billy Brumley wrote: > >>> Hello, > >>> Is there any command-line tool to get the plain text rsa private key > >>> like the following format from .pem file? > >> > >> openssl rsa -in mykey.pem -noout -text > > > > It would in fact be much more educational to advocate pkey, which is > > cryptosystem agnostic > > Good point! > > Matt > > > > > openssl pkey -in mykey.pem -noout -text > > > > Since I would expect the rsa command to go the same was as the rsautl > > command in the future. > > > > Happy Friday! > > > > BBB > > >
Re: How to get rsa-private key in plain text format?
On 03/09/2021 14:49, Billy Brumley wrote: Hello, Is there any command-line tool to get the plain text rsa private key like the following format from .pem file? openssl rsa -in mykey.pem -noout -text It would in fact be much more educational to advocate pkey, which is cryptosystem agnostic Good point! Matt openssl pkey -in mykey.pem -noout -text Since I would expect the rsa command to go the same was as the rsautl command in the future. Happy Friday! BBB
Re: How to get rsa-private key in plain text format?
> > Hello, > > Is there any command-line tool to get the plain text rsa private key > > like the following format from .pem file? > > openssl rsa -in mykey.pem -noout -text It would in fact be much more educational to advocate pkey, which is cryptosystem agnostic openssl pkey -in mykey.pem -noout -text Since I would expect the rsa command to go the same was as the rsautl command in the future. Happy Friday! BBB
Re: How to get rsa-private key in plain text format?
On 03/09/2021 00:21, Shariful Alam wrote: Hello, Is there any command-line tool to get the plain text rsa private key like the following format from .pem file? openssl rsa -in mykey.pem -noout -text Matt
Re: How to get rsa-private key in plain text format?
On Thu, Sep 02, 2021 at 05:21:22PM -0600, Shariful Alam wrote: > Is there any command-line tool to get the plain text rsa private key like > the following format from .pem file? Yes, if you're willing to tolerate slightly different labels and ":" every two nibbles.With slightly different labels and ":" every two nibbles. For example: $ openssl genrsa 512 2>&1 | openssl rsa -text -noout RSA Private-Key: (512 bit, 2 primes) modulus: 00:d6:e5:14:e0:d9:42:e4:11:81:e5:cd:33:11:24: 7f:3b:08:d7:ba:16:1e:01:05:37:65:c3:41:b8:df: 3c:df:af:a3:e0:a3:02:fc:e6:20:3d:f2:c6:cc:bf: 03:0c:c0:4b:8a:78:2b:8b:55:2e:f8:3e:81:10:e9: d9:b2:46:d2:7d publicExponent: 65537 (0x10001) privateExponent: 67:e3:59:a3:96:05:0b:83:17:3c:44:66:92:bc:05: 32:42:05:20:b6:3e:8d:19:bb:7d:5b:d6:f3:0c:21: 3e:b5:a4:bd:1d:01:02:c5:37:b9:e3:ed:fb:60:33: eb:d4:f0:9f:fd:03:6d:e9:64:42:85:3d:dd:57:51: 0c:63:57:f5 prime1: 00:f6:d6:33:68:9c:5b:3e:74:7c:95:36:e1:f3:7f: 82:0d:e7:aa:65:f4:36:51:46:c0:83:92:cc:da:60: 9d:47:83 prime2: 00:de:df:52:aa:da:a9:95:06:92:e7:32:b4:28:3c: 69:58:17:31:10:69:80:89:41:f1:6f:4b:9a:7c:3f: 36:5d:ff exponent1: 19:c9:d1:3f:29:ae:c2:bc:aa:d3:70:13:75:3c:2a: 1b:47:cb:de:b1:00:07:c7:cb:8f:33:84:21:80:9c: 8d:ff exponent2: 00:d1:48:7a:53:50:13:f0:8a:04:c6:af:f9:36:d3: 4b:c4:d9:ba:4c:04:16:1c:4d:dd:0e:ba:ba:ed:b3: 5a:35:37 coefficient: 00:9f:ec:87:75:7f:31:c3:f8:17:fc:c7:c0:f4:0e: ec:2a:a5:e4:52:e1:ed:1b:c4:5a:a8:fa:35:22:28: 1f:e5:c3 -- Viktor.
How to get rsa-private key in plain text format?
Hello, Is there any command-line tool to get the plain text rsa private key like the following format from .pem file? N = D0C2ACDCF780B1E4846054BDA700F18D567247FE8BC5BA4FBCAB814E619DA63A20F65A58EE89FC0824DC9367C5725BDDC596065F1C8868E99C896F3A0CF7D7F0A785E668F2568F19BAFB8FF3BA5CDF487544EFE71010BEDB4EE16EDC3AF0A71391AD3194B42D3FD40B4E0DE12A22D8188AF03FF4E36D37BA1DA1F3C57188E60DA38C25329E48805FC7FF524761A6F010E737B927D8F67383274F8E600167A52A042E1DCA3335150C090803F9D96F6E63BEBFB153516E863F5B4CB02104077834FC5EC31A47451783931D643CE736DD1BAB40C5523858BB067FB9E490DCB5FDBBB03B9D68A8998C1347E237C477AA14B0997A84708CED05A9E24C7072B838F753 E = 010001 D = 21AFE07431CE47269083F8F8B7ABCBCEDA6DCB975457BE6662942C64091586FEE755C9A3832EAA0868665DB507A41A15F1EDF12E44ECF03D0E6D457D730FA700D0FB0B6C13607C0F5F1DDDEB61AE9019E53A9C998F2AD5924430EEA3E9DA1B0E5F2B575DDBE86C4096B5C87661F7A7E7F7F21D0701509BBA881B4AE463F6F18C7F04AB742319E2D7319EECA136EEB0CF7B2BFA87E3A0E69FBC0E5FDC7EE6271EB2CA09DDBF7C8B57D951762708D76890E62858C1D5FC5B7E40D50913CE7797BD80F6A398FB92703FBDD33FBCB129B86E54F13EC14DA68BE139634DD1E9C01F01751C427B029AF629EED23C99726F0A0C3CEA1229E4099B588CE676975D25 P = FD1120F3E183DF72779B9B4A29FF9157C89FF8204988B6FB1211642B4D59B6A1BB306E81C040F0F822B41765FC4435A46B5090700E72B9720481EACF3624885D7A263CAC0CA559954E9382FCC7D57221CD9394C64585653664976174CAE2E7DC6A7B03DE09599B5D9501927ACC4EED5F5CBC5870E31A051AF9842945A0168E35 Q = D32E15E032B256C7DE0BDB585379EB897343ABFB8C7A86A3D798C13AE3E3F048A50DA9D7C31EB65A588CF6B9911F7B41D6F154F99B4F64839E110C30BA4B79286A4A3A3F7F0169A1D3A21F0D084CFA423E04C90C5966AC391A47F10E823C71B9716856B05BC12160DF0BA96300F8ADDC0D59E54E9CBDC7AC0EA6747DBA46C067 DP = 2004DECA7CAA16C780E2AB4F42E91716A847B53940948FB24CA2EEAD9BE7D1F7BC9B701FF29744E5E05E30E7B2775EE222C1DAC492CF692F47EAB82EE786CFCA23FE5A86DA42C186E69E3B608858354C999A26A4BF7F1543408EF6C1B439E9643604C2848162590A0A245CC834B977C72D10979010EBE5E177D884F04E450C51 DQ = 9A035E48E8305041EB9AD21994A7B233C8306E59429689632C7567573FA4993521CAD93756422BD3B008FE574F939A1CE659931387455B94F1CE950964946E841F208B628B89C83411588734C5FCFDF719ABFBC459DF1B7379CB45EEC2E4BA3BF88D93CB82DF532C86FEC646420B1B21054BAE84AAA36DDFF9BF43EDFDD063B9 QP = E7A5BC150E6A20E52920C6F24FC872B1893ED9268AA506D86EC3AA6E3B377E5F6AE0D686751CE40F684435C6F64F3161389CE430FB271EE81D0067ED8A1BD8096FB3E4AF5839383F26F99916EED4D80CFA9B5901350A9C0AAD4E348EBCC559F92434C71DA864C13371626D9F29998748BB3C47BED31471B73ABF2E27B983 If no such tool exists, Can anyone please give me an idea, how can extract keys like the above format from a .pem file? Regards, Shariful Alam
Re: Consultation:Additional “ephemeral public key” and “ephemeral private key" implementations for quictls/opens
Dear OpenSSL users Thanks for thinking about it. (Especially grateful to Mr./Ms. Mattl, Michael and Kris. ) I took a little time to clarify our questions. The attached document is a diagram of our idea of how the original protocol and TLS should work together. Objective: We want to implement QUIC-TLS, which is lightweight and secure. Specifically, we would like to implement a handshake protocol by incorporating non-standard protocols. For example, we are considering a post-quantum key exchange protocol. This is just a part of our research, and we are not considering a new standardization proposal for TLS handshaking that includes the above protocols at this stage. What we would like to hear: 1. what exactly is the structure that stores ephemeral keys in ECDHE/DHE? 2. What is the function that calculates the ephemeral public key of ECDHE/DHE and stores the value in the above structure? 3. After receiving a client hello or server hello message, where is the part that extracts the ephemeral public key of the communication partner from the received message? Also, where is the place to calculate the session key from ECDHE/DHE? Additional two information. Current situation: I'm trying to implement it using "msquic". The handshake in "msquic" uses "quictls" forked from OpenSSL, but I think the implementation of the TLS handshake is based on OpenSSL. Problem: I would like to be able to use the TLS handshake part of OpenSSL (ClientHello, ServerHello) with protocol messages on behalf of ECDHE and DHE to perform key exchange and pass the generated session key to the TLS record protocol. Nobuo Aoki (master 1st student, Japan). (It seems that the file could not be attached because of the large sending byte size. Instead, I'll share it from my university's storage. Here is the link for sharing) https://hunet-my.sharepoint.com/:i:/g/personal/mg66001_e_hiroshima-cu_ac_jp/Ecmdv1CofjZCniQ9vWFSLu4Bjfm7bYuShGcdG1J0IRZzjQ?e=p5s3uV <https://hunet-my.sharepoint.com/:i:/g/personal/mg66001_e_hiroshima-cu_ac_jp/Ecmdv1CofjZCniQ9vWFSLu4Bjfm7bYuShGcdG1J0IRZzjQ?e=p5s3uV> > 2021/08/30 16:57、Matt Caswell のメール: > > > > On 29/08/2021 20:41, Nobuo Aoki wrote: >> I am trying to identify the implementation >> where “ephemeral public key” and “ephemeral private key” can be added, > > I am unclear from your question whether you are asking how to add a new > public/private key scheme for integration into TLS. Or whether you are simply > asking for the location in the code where the key_share is generated. If the > latter then you might look here for the client side: > > https://github.com/openssl/openssl/blob/e8e1f6d1a9e599d575431f559200018b8f822e0f/ssl/statem/extensions_clnt.c#L649-L705 > > And here for the server side: > > https://github.com/openssl/openssl/blob/e8e1f6d1a9e599d575431f559200018b8f822e0f/ssl/statem/extensions_srvr.c#L1577-L1707 > > > Matt >
Re: RSA private key DER decode fails without CRT components
Hi, I could see this with openssl version 1.1.1d. Sure I'll update. On Tue, Aug 31, 2021 at 1:34 PM Dmitry Belyavsky wrote: > Hello, > > First, may I ask you which version of OpenSSL do you use? > Secondly, could you please report the issue via GitHub to make sure that > it will not be lost? > > On Tue, Aug 31, 2021 at 10:01 AM Brahmaji K wrote: > >> Hi Team, >> >> I'm trying to decode the RSA private key which was DER encoded earlier >> without CRT components (p, q, dmp1, dmq1 and iqmp is NULL). I'm using the >> same openssl version for both encoding and decoding, encoding works fine >> but decode fails. In decode, we call EVP_PKEY2PKCS8() function, this is >> failing with below error: >> >> 469393408:error:0D078079:asn1 encoding routines:asn1_item_embed_d2i:field >> missing:crypto/asn1/tasn_dec.c:425:Field=p, Type=RSAPrivateKey >> >> The above error is because field p is NULL, but with same p is NULL >> encoding is successful. Any idea why encode is Success but decode fails? >> >> Thanks and Regards, >> Brahmaji K >> > > > -- > SY, Dmitry Belyavsky >
Re: RSA private key DER decode fails without CRT components
Hello, First, may I ask you which version of OpenSSL do you use? Secondly, could you please report the issue via GitHub to make sure that it will not be lost? On Tue, Aug 31, 2021 at 10:01 AM Brahmaji K wrote: > Hi Team, > > I'm trying to decode the RSA private key which was DER encoded earlier > without CRT components (p, q, dmp1, dmq1 and iqmp is NULL). I'm using the > same openssl version for both encoding and decoding, encoding works fine > but decode fails. In decode, we call EVP_PKEY2PKCS8() function, this is > failing with below error: > > 469393408:error:0D078079:asn1 encoding routines:asn1_item_embed_d2i:field > missing:crypto/asn1/tasn_dec.c:425:Field=p, Type=RSAPrivateKey > > The above error is because field p is NULL, but with same p is NULL > encoding is successful. Any idea why encode is Success but decode fails? > > Thanks and Regards, > Brahmaji K > -- SY, Dmitry Belyavsky
RSA private key DER decode fails without CRT components
Hi Team, I'm trying to decode the RSA private key which was DER encoded earlier without CRT components (p, q, dmp1, dmq1 and iqmp is NULL). I'm using the same openssl version for both encoding and decoding, encoding works fine but decode fails. In decode, we call EVP_PKEY2PKCS8() function, this is failing with below error: 469393408:error:0D078079:asn1 encoding routines:asn1_item_embed_d2i:field missing:crypto/asn1/tasn_dec.c:425:Field=p, Type=RSAPrivateKey The above error is because field p is NULL, but with same p is NULL encoding is successful. Any idea why encode is Success but decode fails? Thanks and Regards, Brahmaji K
Re: Consultation:Additional “ephemeral public key” and “ephemeral private key" implementations for quictls/opens
On 29/08/2021 20:41, Nobuo Aoki wrote: I am trying to identify the implementation where “ephemeral public key” and “ephemeral private key” can be added, I am unclear from your question whether you are asking how to add a new public/private key scheme for integration into TLS. Or whether you are simply asking for the location in the code where the key_share is generated. If the latter then you might look here for the client side: https://github.com/openssl/openssl/blob/e8e1f6d1a9e599d575431f559200018b8f822e0f/ssl/statem/extensions_clnt.c#L649-L705 And here for the server side: https://github.com/openssl/openssl/blob/e8e1f6d1a9e599d575431f559200018b8f822e0f/ssl/statem/extensions_srvr.c#L1577-L1707 Matt
Re: Consultation:Additional “ephemeral public key” and “ephemeral private key" implementations for quictls/opens
Hi Nobuo, I'm afraid a bit more details are needed. Not sure, what you mean by "enabling ephemeral key for SSL/TLS". For example, TLSv1.3 uses only key exchanges that offer forward secrecy, so one way to "enable ephemeral" is to use this new version of TLS protocol. If you wish see an example of such integration, then open-quantum-safe project [1] is maybe one place to look at. Those guys have integrated post-quantum key exchanges (ephemeral) into openssl. Lot's of good examples there. The OpenSSLNTRU [2] does similar thing and maybe is simpler to understand. Kind regards, Kris [1] https://github.com/open-quantum-safe/openssl [2] https://opensslntru.cr.yp.to/demo.html On 8/29/21 8:41 PM, Nobuo Aoki wrote: > Dear OpenSSL users (reshaped) > > My name is Nobuo Aoki, > and I am a master's student. > (Hiroshima City University, Japan) > > Right now, I am doing research on secure communication protocols. > Specifically, we are trying to enable “ephemeral public key” and > “ephemeral private key” for SSL/TLS. > > I have been using quictls/openssl as an implementation of SSL/TLS. > It is publicly available on Github. > I am trying to identify the implementation > where “ephemeral public key” and “ephemeral private key” can be added, > but I have not been able to do so yet, > probably because I am not familiar with the openssl implementation. > I have also tried to read openssl/openssl in order to identify the > implementation, but no luck. > > So, I'm wondering if those who are familiar with > the openssl implementation can lend me some great help. > Any advice would be greatly appreciated. > > —— > Nobuo Aoki (master 1st-year student) > Email : b20001s...@gmail.com <mailto:b20001s...@gmail.com> > Tel or SMS : +8170-8516-4157 > Laboratory of Information Network > Department of Computer and Network Engineering > Graduate School of Information Sciences, > Hiroshima City University > >> Dear OpenSSL users >> >> My name is Nobuo Aoki, >> and I am a master's student. >> (Hiroshima City University, Japan) >> >> Right now, I am doing research on secure communication protocols. >> Specifically, we are trying to enable “ephemeral public key” and >> “ephemeral private key” for SSL/TLS. >> >> I have been using quictls/openssl as an implementation of SSL/TLS. >> It is publicly available on Github. >> I am trying to identify the implementation >> where “ephemeral public key” and “ephemeral private key” can be added, >> but I have not been able to do so yet, >> probably because I am not familiar with the openssl implementation. >> I have also tried to read openssl/openssl in order to identify the >> implementation, but no luck. >> >> So, I'm wondering if those who are familiar with >> the openssl implementation can lend me some great help. >> Any advice would be greatly appreciated. >> >> —— >> Aoki Nobuo (master 1st-year student) >> Email : b20001s...@gmail.com <mailto:b20001s...@gmail.com> >> Tel or SMS : +8170-8516-4157 >> Laboratory of Information Network >> Department of Computer and Network Engineering >> Graduate School of Information Sciences, >> Hiroshima City University >> >
RE: Consultation:Additional “ephemeral public key” and “ephemeral private key" implementations for quictls/opens
> From: openssl-users On Behalf Of > Sent: Sunday, 29 August, 2021 07:04 > Specifically, we are trying to enable “ephemeral public key” and > “ephemeral private key" for SSL/TLS. I'm afraid it is not clear to me, at least, what you are trying to do. Are you attempting to implement a standard protocol that incorporates ephemeral key pairs, such as EKE, into TLS? Are you implementing a standard specifically for TLS that I'm not aware of? (That's quite possible; I don't follow TLS standards closely.) If not, what is your use case? How do you see your protocol interacting with TLS? Some might argue that OpenSSL is not especially well-suited for adding experimental ciphersuites and protocols to its TLS implementation. Its focus is on providing a secure and rich commercial implementation of TLS and various cryptographic operations and protocols, not on providing a toolkit for researchers. I've never used quictls (as I think QUIC is broadly undesirable for most applications), but my understanding is that it's a fork of OpenSSL, so it's probably not any better in that regard. -- Michael Wojcik
Re: Consultation:Additional “ephemeral public key” and “ephemeral private key" implementations for quictls/opens
Dear OpenSSL users (reshaped) My name is Nobuo Aoki, and I am a master's student. (Hiroshima City University, Japan) Right now, I am doing research on secure communication protocols. Specifically, we are trying to enable “ephemeral public key” and “ephemeral private key” for SSL/TLS. I have been using quictls/openssl as an implementation of SSL/TLS. It is publicly available on Github. I am trying to identify the implementation where “ephemeral public key” and “ephemeral private key” can be added, but I have not been able to do so yet, probably because I am not familiar with the openssl implementation. I have also tried to read openssl/openssl in order to identify the implementation, but no luck. So, I'm wondering if those who are familiar with the openssl implementation can lend me some great help. Any advice would be greatly appreciated. —— Nobuo Aoki (master 1st-year student) Email : b20001s...@gmail.com Tel or SMS : +8170-8516-4157 Laboratory of Information Network Department of Computer and Network Engineering Graduate School of Information Sciences, Hiroshima City University > Dear OpenSSL users > > My name is Nobuo Aoki, > and I am a master's student. > (Hiroshima City University, Japan) > > Right now, I am doing research on secure communication protocols. > Specifically, we are trying to enable “ephemeral public key” and > “ephemeral private key” for SSL/TLS. > > I have been using quictls/openssl as an implementation of SSL/TLS. > It is publicly available on Github. > I am trying to identify the implementation > where “ephemeral public key” and “ephemeral private key” can be added, > but I have not been able to do so yet, > probably because I am not familiar with the openssl implementation. > I have also tried to read openssl/openssl in order to identify the > implementation, but no luck. > > So, I'm wondering if those who are familiar with > the openssl implementation can lend me some great help. > Any advice would be greatly appreciated. > > —— > Aoki Nobuo (master 1st-year student) > Email : b20001s...@gmail.com > Tel or SMS : +8170-8516-4157 > Laboratory of Information Network > Department of Computer and Network Engineering > Graduate School of Information Sciences, > Hiroshima City University >
Consultation:Additional “ephemeral public key” and “ephemeral private key" implementations for quictls/opens
Dear OpenSSL users My name is Nobuo Aoki, and I am a master's student. (Hiroshima City University, Japan) Right now, I am doing research on secure communication protocols. Specifically, we are trying to enable “ephemeral public key” and “ephemeral private key" for SSL/TLS. I have been using quictls/openssl as an implementation of SSL/TLS. It is publicly available on Github. I am trying to identify the implementation where “ephemeral public key” and “ephemeral private key" can be added, but I have not been able to do so yet, probably because I am not familiar with the openssl implementation. I have also tried to read openssl/openssl in order to identify the implementation, but no luck. So, I'm wondering if those who are familiar with the openssl implementation can lend me some great help. Any advice would be greatly appreciated. —— Aoki Nobuo(2166001) Email : b20001s...@gmail.com <mailto:b20001s...@gmail.com> Tel or SMS : +8170-8516-4157 Laboratory of Information Network Department of Computer and Network Engineering Graduate School of Information Sciences, Hiroshima City University
Re: Public key from TSS2 private key with OpenSSL 3.0.0-beta2
Dear Dmitry, I just submitted a new issue, #16256. Thank you, Nestor Melo From: Dmitry Belyavsky Sent: Friday, August 6, 2021 12:21 PM To: Nestor Melo Cc: openssl-users@openssl.org Subject: Re: Public key from TSS2 private key with OpenSSL 3.0.0-beta2 Dear Nestor, Could you please fill an issue on GitHub? It's much simpler for us to follow the issues there. On Fri, Aug 6, 2021 at 9:13 PM Nestor Melo mailto:nestor.m...@zpesystems.com>> wrote: Greetings, We use a TPM2 device to generate private keys with tpm2-tss-engine: https://github.com/tpm2-software/tpm2-tss-engine While attempting to extract the public key from a TSS2 private key using OpenSSL 3.0.0-beta2 and tpm2-tss-engine, I received a message "PEM format not supported": openssl rsa -engine libtpm2tss -inform engine -in privkey.pem -pubout -outform PEM -out pubkey.pem Engine "tpm2tss" set. writing RSA key PEM format not supported Although it is recommended to use providers instead of engines with OpenSSL 3.0.0, are engines still supported? Should the above operation be expected to work? Here is an example of a private key was generated with tpm2-tss-engine's tpm2tss-genkey: -BEGIN TSS2 PRIVATE KEY- MIIB8gYGZ4EFCgEDoAMBAQECBEEEggEYARYAAQALAAYEcgAAABAAEAgAAAEA AQEAmT8O+ikRX5eTRUsDXrBAephW1YLEITkKxviFzIxF7R1K1jlDIXI8PKhc6tUE sEDfgTNtldmc3nxPmJBxeAzIQrGAAUjGY74xtvbe6T6muU9FHGVpw1e3LelewFCQ yR+t36GaOBY+S4Bc0DC0KhSoFakiwYt2vtQvm0W54cwxg7B4aSfcBUNHFPB5J90c ere/o20QpNvb7mw/kwvoTSzsyQT5qMZALKZeRFZ42991dGWJpnfC30xieXCMoD7z x5hhc5Uf5EbFtxeWaT2HTfs0h0OxigQSjXdmCJPeJVoMPOoF2FK+PbZwPn2UDKyo SqhsmZ+9hvkUWylDYiXfm24TUwSBwAC+ACDJpk4p0h4Q3UEtwph3oNy5xR7hya4S XHqabuThC+xX1AAQDTukmp9lruULdnZALN1Lyw1AMw+7F2BBx786jjOmg9rX+umB ffGZSs187UAjmfe98XUk9oNsZkgB7HEsDRIOXoET+9R0KI48whV3Z/Kwag+UmErL KRTOl5zEUenbQi8/CBDVpuxKMyKl6tYc38iNh2rA8Eju9tv+x6kPv/5/JxmXSpgQ rCSHxBQFxnnITejU/RMqCHMZpCly2A== -END TSS2 PRIVATE KEY- If I use instead the TPM2 provider tpm2-openssl https://github.com/tpm2-software/tpm2-openssl the command openssl rsa -provider tpm2 -in privkey.pem -pubout -outform PEM -out pubkey.pem works, producing: -BEGIN PUBLIC KEY- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmT8O+ikRX5eTRUsDXrBA ephW1YLEITkKxviFzIxF7R1K1jlDIXI8PKhc6tUEsEDfgTNtldmc3nxPmJBxeAzI QrGAAUjGY74xtvbe6T6muU9FHGVpw1e3LelewFCQyR+t36GaOBY+S4Bc0DC0KhSo FakiwYt2vtQvm0W54cwxg7B4aSfcBUNHFPB5J90cere/o20QpNvb7mw/kwvoTSzs yQT5qMZALKZeRFZ42991dGWJpnfC30xieXCMoD7zx5hhc5Uf5EbFtxeWaT2HTfs0 h0OxigQSjXdmCJPeJVoMPOoF2FK+PbZwPn2UDKyoSqhsmZ+9hvkUWylDYiXfm24T UwIDAQAB -END PUBLIC KEY- Thank you, Nestor Melo -- SY, Dmitry Belyavsky
Re: Public key from TSS2 private key with OpenSSL 3.0.0-beta2
Dear Nestor, Could you please fill an issue on GitHub? It's much simpler for us to follow the issues there. On Fri, Aug 6, 2021 at 9:13 PM Nestor Melo wrote: > Greetings, > > > We use a TPM2 device to generate private keys with tpm2-tss-engine: > https://github.com/tpm2-software/tpm2-tss-engine > > While attempting to extract the public key from a TSS2 private key using > OpenSSL 3.0.0-beta2 and tpm2-tss-engine, I received a message "PEM format > not supported": > > openssl rsa -engine libtpm2tss -inform engine -in privkey.pem -pubout > -outform PEM -out pubkey.pem > Engine "tpm2tss" set. > writing RSA key > PEM format not supported > > Although it is recommended to use providers instead of engines with > OpenSSL 3.0.0, are engines still supported? Should the above operation be > expected to work? > > Here is an example of a private key was generated with tpm2-tss-engine's > tpm2tss-genkey: > -BEGIN TSS2 PRIVATE KEY- > MIIB8gYGZ4EFCgEDoAMBAQECBEEEggEYARYAAQALAAYEcgAAABAAEAgAAAEA > AQEAmT8O+ikRX5eTRUsDXrBAephW1YLEITkKxviFzIxF7R1K1jlDIXI8PKhc6tUE > sEDfgTNtldmc3nxPmJBxeAzIQrGAAUjGY74xtvbe6T6muU9FHGVpw1e3LelewFCQ > yR+t36GaOBY+S4Bc0DC0KhSoFakiwYt2vtQvm0W54cwxg7B4aSfcBUNHFPB5J90c > ere/o20QpNvb7mw/kwvoTSzsyQT5qMZALKZeRFZ42991dGWJpnfC30xieXCMoD7z > x5hhc5Uf5EbFtxeWaT2HTfs0h0OxigQSjXdmCJPeJVoMPOoF2FK+PbZwPn2UDKyo > SqhsmZ+9hvkUWylDYiXfm24TUwSBwAC+ACDJpk4p0h4Q3UEtwph3oNy5xR7hya4S > XHqabuThC+xX1AAQDTukmp9lruULdnZALN1Lyw1AMw+7F2BBx786jjOmg9rX+umB > ffGZSs187UAjmfe98XUk9oNsZkgB7HEsDRIOXoET+9R0KI48whV3Z/Kwag+UmErL > KRTOl5zEUenbQi8/CBDVpuxKMyKl6tYc38iNh2rA8Eju9tv+x6kPv/5/JxmXSpgQ > rCSHxBQFxnnITejU/RMqCHMZpCly2A== > -END TSS2 PRIVATE KEY- > > If I use instead the TPM2 provider tpm2-openssl > https://github.com/tpm2-software/tpm2-openssl > > the command > openssl rsa -provider tpm2 -in privkey.pem -pubout -outform PEM -out > pubkey.pem > > works, producing: > -BEGIN PUBLIC KEY- > MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmT8O+ikRX5eTRUsDXrBA > ephW1YLEITkKxviFzIxF7R1K1jlDIXI8PKhc6tUEsEDfgTNtldmc3nxPmJBxeAzI > QrGAAUjGY74xtvbe6T6muU9FHGVpw1e3LelewFCQyR+t36GaOBY+S4Bc0DC0KhSo > FakiwYt2vtQvm0W54cwxg7B4aSfcBUNHFPB5J90cere/o20QpNvb7mw/kwvoTSzs > yQT5qMZALKZeRFZ42991dGWJpnfC30xieXCMoD7zx5hhc5Uf5EbFtxeWaT2HTfs0 > h0OxigQSjXdmCJPeJVoMPOoF2FK+PbZwPn2UDKyoSqhsmZ+9hvkUWylDYiXfm24T > UwIDAQAB > -END PUBLIC KEY- > > > Thank you, > > Nestor Melo > > > -- SY, Dmitry Belyavsky
Public key from TSS2 private key with OpenSSL 3.0.0-beta2
Greetings, We use a TPM2 device to generate private keys with tpm2-tss-engine: https://github.com/tpm2-software/tpm2-tss-engine While attempting to extract the public key from a TSS2 private key using OpenSSL 3.0.0-beta2 and tpm2-tss-engine, I received a message "PEM format not supported": openssl rsa -engine libtpm2tss -inform engine -in privkey.pem -pubout -outform PEM -out pubkey.pem Engine "tpm2tss" set. writing RSA key PEM format not supported Although it is recommended to use providers instead of engines with OpenSSL 3.0.0, are engines still supported? Should the above operation be expected to work? Here is an example of a private key was generated with tpm2-tss-engine's tpm2tss-genkey: -----BEGIN TSS2 PRIVATE KEY- MIIB8gYGZ4EFCgEDoAMBAQECBEEEggEYARYAAQALAAYEcgAAABAAEAgAAAEA AQEAmT8O+ikRX5eTRUsDXrBAephW1YLEITkKxviFzIxF7R1K1jlDIXI8PKhc6tUE sEDfgTNtldmc3nxPmJBxeAzIQrGAAUjGY74xtvbe6T6muU9FHGVpw1e3LelewFCQ yR+t36GaOBY+S4Bc0DC0KhSoFakiwYt2vtQvm0W54cwxg7B4aSfcBUNHFPB5J90c ere/o20QpNvb7mw/kwvoTSzsyQT5qMZALKZeRFZ42991dGWJpnfC30xieXCMoD7z x5hhc5Uf5EbFtxeWaT2HTfs0h0OxigQSjXdmCJPeJVoMPOoF2FK+PbZwPn2UDKyo SqhsmZ+9hvkUWylDYiXfm24TUwSBwAC+ACDJpk4p0h4Q3UEtwph3oNy5xR7hya4S XHqabuThC+xX1AAQDTukmp9lruULdnZALN1Lyw1AMw+7F2BBx786jjOmg9rX+umB ffGZSs187UAjmfe98XUk9oNsZkgB7HEsDRIOXoET+9R0KI48whV3Z/Kwag+UmErL KRTOl5zEUenbQi8/CBDVpuxKMyKl6tYc38iNh2rA8Eju9tv+x6kPv/5/JxmXSpgQ rCSHxBQFxnnITejU/RMqCHMZpCly2A== -END TSS2 PRIVATE KEY- If I use instead the TPM2 provider tpm2-openssl https://github.com/tpm2-software/tpm2-openssl the command openssl rsa -provider tpm2 -in privkey.pem -pubout -outform PEM -out pubkey.pem works, producing: -BEGIN PUBLIC KEY- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmT8O+ikRX5eTRUsDXrBA ephW1YLEITkKxviFzIxF7R1K1jlDIXI8PKhc6tUEsEDfgTNtldmc3nxPmJBxeAzI QrGAAUjGY74xtvbe6T6muU9FHGVpw1e3LelewFCQyR+t36GaOBY+S4Bc0DC0KhSo FakiwYt2vtQvm0W54cwxg7B4aSfcBUNHFPB5J90cere/o20QpNvb7mw/kwvoTSzs yQT5qMZALKZeRFZ42991dGWJpnfC30xieXCMoD7zx5hhc5Uf5EbFtxeWaT2HTfs0 h0OxigQSjXdmCJPeJVoMPOoF2FK+PbZwPn2UDKyoSqhsmZ+9hvkUWylDYiXfm24T UwIDAQAB -END PUBLIC KEY- Thank you, Nestor Melo
Re: "Expecting: ANY PRIVATE KEY"
> On 28.06.2021, at 01:02, Michel wrote: > > Hi Mariano, > > My quick answer : your key file looks like an (old ?) custom *OpenSSH* format > that *OpenSSL* cannot read natively. > You should easily find an OpenSSH command or other free tools to converts > between formats. > > Hope it helps, > > Michel. > Hello Michel! Thank you for your prompt response. I will follow your advice. I did try some OpenSSH options before (ssh-keygen -i and such) but kept getting errors. Reason why I’m so insistent is because I got locked out from my VM for some odd reason, and all contingencies do not seem to work, so I guess I would try to gain access through cloud console, and also learn from this experience. I will dig more into the OpenSSH side of things. Thanks again! --Mariano > -Message d'origine- > De : openssl-users [mailto:openssl-users-boun...@openssl.org] De la part de > Mariano Gedisman-Córdoba via openssl-users > Envoyé : lundi 28 juin 2021 00:29 > À : openssl-users@openssl.org > Objet : "Expecting: ANY PRIVATE KEY" > > Hello everyone! > I have googled this error to no avail, but all answers don’t seem to adjust > to my particular case, or maybe I’m too novice at figuring it out. > > I have this key file: > > -BEGIN OPENSSH PRIVATE KEY—— > [key here] > -END OPENSSH PRIVATE KEY—— > > I’m trying to use this key in order to log in to my Google cloud instance > through browser console, and I get the following error: > "Error: Failed to read key. The key file must be ECDSA or RSA in PEM format. " > > I googled how to achieve this, and tried the following on my local machine: > $ openssl rsa -in id_rsa.txt -out id_rsa.pem -outform PEM > > Sadly, I run into this error: > unable to load Private Key > 56081:error:0906D06C:PEM routines:PEM_read_bio:no start > line:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.2/src/crypto/pem/pem_lib.c:648:Expecting: > ANY PRIVATE KEY > > As I said, Google did throw some clues, but nothing conclusive. > Note: I am running OS X El Cap. > > Can anyone point out what am I doing wrong? > > Thanks a lot in advance and I wish you a really good week! >
RE: "Expecting: ANY PRIVATE KEY"
Hi Mariano, My quick answer : your key file looks like an (old ?) custom *OpenSSH* format that *OpenSSL* cannot read natively. You should easily find an OpenSSH command or other free tools to converts between formats. Hope it helps, Michel. -Message d'origine- De : openssl-users [mailto:openssl-users-boun...@openssl.org] De la part de Mariano Gedisman-Córdoba via openssl-users Envoyé : lundi 28 juin 2021 00:29 À : openssl-users@openssl.org Objet : "Expecting: ANY PRIVATE KEY" Hello everyone! I have googled this error to no avail, but all answers don’t seem to adjust to my particular case, or maybe I’m too novice at figuring it out. I have this key file: -BEGIN OPENSSH PRIVATE KEY—— [key here] -----END OPENSSH PRIVATE KEY—— I’m trying to use this key in order to log in to my Google cloud instance through browser console, and I get the following error: "Error: Failed to read key. The key file must be ECDSA or RSA in PEM format. " I googled how to achieve this, and tried the following on my local machine: $ openssl rsa -in id_rsa.txt -out id_rsa.pem -outform PEM Sadly, I run into this error: unable to load Private Key 56081:error:0906D06C:PEM routines:PEM_read_bio:no start line:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.2/src/crypto/pem/pem_lib.c:648:Expecting: ANY PRIVATE KEY As I said, Google did throw some clues, but nothing conclusive. Note: I am running OS X El Cap. Can anyone point out what am I doing wrong? Thanks a lot in advance and I wish you a really good week!
"Expecting: ANY PRIVATE KEY"
Hello everyone! I have googled this error to no avail, but all answers don’t seem to adjust to my particular case, or maybe I’m too novice at figuring it out. I have this key file: -BEGIN OPENSSH PRIVATE KEY—— [key here] -END OPENSSH PRIVATE KEY—— I’m trying to use this key in order to log in to my Google cloud instance through browser console, and I get the following error: "Error: Failed to read key. The key file must be ECDSA or RSA in PEM format. " I googled how to achieve this, and tried the following on my local machine: $ openssl rsa -in id_rsa.txt -out id_rsa.pem -outform PEM Sadly, I run into this error: unable to load Private Key 56081:error:0906D06C:PEM routines:PEM_read_bio:no start line:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.2/src/crypto/pem/pem_lib.c:648:Expecting: ANY PRIVATE KEY As I said, Google did throw some clues, but nothing conclusive. Note: I am running OS X El Cap. Can anyone point out what am I doing wrong? Thanks a lot in advance and I wish you a really good week!
Secure Heap Usage for EC private key
Long shot if someone may know. Secure heap was added long ago for private keys for RSA, DSA and DH however EC key generation does not seem to be included. I see some other EC functions that use secure heap and I also noticed that the CHANGES file stated: "Add secure heap for storage of private keys (when possible)." which leads me to believe there was something about EC key generation that prohibited using secure heap. Any background on the reason for the EC omission ? Thanks, Barry
Re: OpenSSL 3.0.0 APIs for creating an EVP_PKEY from a p256 private key octet string
On 10/03/2021 12:08, Stephen Farrell wrote: It seems a pity that one has to special case in two ways there (both keytype and groupname) but I can live with it, For X25519 you can actually pass a groupname of "x25519" through if you want to keep everything consistent. But it's not strictly necessary since that is the only group supported by that keytype. Matt
Re: OpenSSL 3.0.0 APIs for creating an EVP_PKEY from a p256 private key octet string
Thanks Matt, On 10/03/2021 09:12, Matt Caswell wrote: On 10/03/2021 00:53, Stephen Farrell wrote: Hiya, On 09/03/2021 03:09, Benjamin Kaduk wrote: I would have expected that the API should hide the differences other than the group name ... but these APIs are still pretty new to me, too. If you can point me at your code I might have more to say. So again it's probably my fault but I'm still not seeing the same behaviour for NIST and non-NIST curves. I made up what I hope is a fairly simple bit of test code [1] so that might help clarify where I'm wrong or (less likely) where a change in the library might be useful. As I build the test code, the p256 cases seem to work, with or without the public key, but both 25519 cases fail. In my (still untidy:-) HPKE code EVP_PKEY_new_raw_private_key for the non-NIST curves works, but not for NIST curves. So I have an ok workaround, even if the fault's not mine, which it of course probably is:-) Hi Stephen There are two important things to understand that your code was not quite handling correctly: 1) X25519/X448/ED25519/ED448 are treated as different key types to "traditional" EC. They really are very different things: different OIDs, different standards, different file formats, different key formats etc. So while the "traditional" EC curves have the key type "EC", we have separate key types of "X25519", "X448", "ED25519" and "ED448" 2) The type of the parameters is dependent on the key type. So a private key in "EC" is an integer. But a private key for "X25519" is an octet string. I had tried all those, but not in the right combination, so thanks! My test code works now with your changes. (It's still at [1] and feel free to use as an example if that's useful.) It seems a pity that one has to special case in two ways there (both keytype and groupname) but I can live with it, Thanks again, S. [1] https://github.com/sftcd/happykey/blob/master/test2evp.c Refer to: https://www.openssl.org/docs/manmaster/man7/EVP_PKEY-EC.html https://www.openssl.org/docs/manmaster/man7/EVP_PKEY-X25519.html I made these changes to your test code to get it to work: $ diff -u test2evp.c test2evp2.c --- test2evp.c 2021-03-10 08:47:59.467451154 + +++ test2evp2.c 2021-03-10 09:03:47.258657721 + @@ -29,6 +29,7 @@ #include int bufs2evp( + const char *keytype, char *groupname, unsigned char *privbuf, size_t privbuflen, unsigned char *pubuf, size_t pubuflen, @@ -41,38 +42,38 @@ OSSL_PARAM_BLD *param_bld=NULL;; OSSL_PARAM *params = NULL; - priv = BN_bin2bn(privbuf, privbuflen, NULL); - if (!priv) { - erv=__LINE__; goto err; - } param_bld = OSSL_PARAM_BLD_new(); if (!param_bld) { erv=__LINE__; goto err; } if (pubuf && pubuflen>0) { - if (OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", groupname,0)!=1) { - erv=__LINE__; goto err; - } - if (OSSL_PARAM_BLD_push_BN(param_bld, "priv", priv)!=1) { - erv=__LINE__; goto err; - } if (OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", pubuf, pubuflen)!=1) { erv=__LINE__; goto err; } params = OSSL_PARAM_BLD_to_param(param_bld); - } else { - if (OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", groupname,0)!=1) { + } + if (groupname != NULL && OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", groupname,0)!=1) { + erv=__LINE__; goto err; + } + if (strcmp(keytype, "EC") == 0) { + priv = BN_bin2bn(privbuf, privbuflen, NULL); + if (!priv) { erv=__LINE__; goto err; - } + } if (OSSL_PARAM_BLD_push_BN(param_bld, "priv", priv)!=1) { erv=__LINE__; goto err; } - params = OSSL_PARAM_BLD_to_param(param_bld); + } else { + if (OSSL_PARAM_BLD_push_octet_string(param_bld, "priv", privbuf, privbuflen)!=1) { + erv=__LINE__; goto err; + } } + params = OSSL_PARAM_BLD_to_param(param_bld); + if (!params) { erv=__LINE__; goto err; } - ctx = EVP_PKEY_CTX_new_from_name(NULL,"EC", NULL); + ctx = EVP_PKEY_CTX_new_from_name(NULL,keytype, NULL); if (ctx == NULL) { erv=__LINE__; goto err; } @@ -167,7 +168,7 @@ * First do a p-256 one that works, then an x25519 one that does not. */ - rv=bufs2evp("P-256",nprivbuf,nprivlen,npubbuf,npublen,&retkey); + rv=bufs2evp("EC","P-256",nprivbuf,nprivlen,npubbuf,npublen,&retkey); if (rv==1) { printf("P-256 with key pair worked\n"); } else { @@ -175,7 +176,7 @@
Re: OpenSSL 3.0.0 APIs for creating an EVP_PKEY from a p256 private key octet string
On 10/03/2021 00:53, Stephen Farrell wrote: Hiya, On 09/03/2021 03:09, Benjamin Kaduk wrote: I would have expected that the API should hide the differences other than the group name ... but these APIs are still pretty new to me, too. If you can point me at your code I might have more to say. So again it's probably my fault but I'm still not seeing the same behaviour for NIST and non-NIST curves. I made up what I hope is a fairly simple bit of test code [1] so that might help clarify where I'm wrong or (less likely) where a change in the library might be useful. As I build the test code, the p256 cases seem to work, with or without the public key, but both 25519 cases fail. In my (still untidy:-) HPKE code EVP_PKEY_new_raw_private_key for the non-NIST curves works, but not for NIST curves. So I have an ok workaround, even if the fault's not mine, which it of course probably is:-) Hi Stephen There are two important things to understand that your code was not quite handling correctly: 1) X25519/X448/ED25519/ED448 are treated as different key types to "traditional" EC. They really are very different things: different OIDs, different standards, different file formats, different key formats etc. So while the "traditional" EC curves have the key type "EC", we have separate key types of "X25519", "X448", "ED25519" and "ED448" 2) The type of the parameters is dependent on the key type. So a private key in "EC" is an integer. But a private key for "X25519" is an octet string. Refer to: https://www.openssl.org/docs/manmaster/man7/EVP_PKEY-EC.html https://www.openssl.org/docs/manmaster/man7/EVP_PKEY-X25519.html I made these changes to your test code to get it to work: $ diff -u test2evp.c test2evp2.c --- test2evp.c 2021-03-10 08:47:59.467451154 + +++ test2evp2.c 2021-03-10 09:03:47.258657721 + @@ -29,6 +29,7 @@ #include int bufs2evp( +const char *keytype, char *groupname, unsigned char *privbuf, size_t privbuflen, unsigned char *pubuf, size_t pubuflen, @@ -41,38 +42,38 @@ OSSL_PARAM_BLD *param_bld=NULL;; OSSL_PARAM *params = NULL; -priv = BN_bin2bn(privbuf, privbuflen, NULL); -if (!priv) { -erv=__LINE__; goto err; -} param_bld = OSSL_PARAM_BLD_new(); if (!param_bld) { erv=__LINE__; goto err; } if (pubuf && pubuflen>0) { -if (OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", groupname,0)!=1) { -erv=__LINE__; goto err; -} -if (OSSL_PARAM_BLD_push_BN(param_bld, "priv", priv)!=1) { -erv=__LINE__; goto err; -} if (OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", pubuf, pubuflen)!=1) { erv=__LINE__; goto err; } params = OSSL_PARAM_BLD_to_param(param_bld); -} else { -if (OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", groupname,0)!=1) { +} +if (groupname != NULL && OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", groupname,0)!=1) { +erv=__LINE__; goto err; +} +if (strcmp(keytype, "EC") == 0) { +priv = BN_bin2bn(privbuf, privbuflen, NULL); +if (!priv) { erv=__LINE__; goto err; -} +} if (OSSL_PARAM_BLD_push_BN(param_bld, "priv", priv)!=1) { erv=__LINE__; goto err; } -params = OSSL_PARAM_BLD_to_param(param_bld); +} else { +if (OSSL_PARAM_BLD_push_octet_string(param_bld, "priv", privbuf, privbuflen)!=1) { +erv=__LINE__; goto err; +} } +params = OSSL_PARAM_BLD_to_param(param_bld); + if (!params) { erv=__LINE__; goto err; } -ctx = EVP_PKEY_CTX_new_from_name(NULL,"EC", NULL); +ctx = EVP_PKEY_CTX_new_from_name(NULL,keytype, NULL); if (ctx == NULL) { erv=__LINE__; goto err; } @@ -167,7 +168,7 @@ * First do a p-256 one that works, then an x25519 one that does not. */ -rv=bufs2evp("P-256",nprivbuf,nprivlen,npubbuf,npublen,&retkey); +rv=bufs2evp("EC","P-256",nprivbuf,nprivlen,npubbuf,npublen,&retkey); if (rv==1) { printf("P-256 with key pair worked\n"); } else { @@ -175,7 +176,7 @@ } EVP_PKEY_free(retkey);retkey=NULL; -rv=bufs2evp("P-256",nprivbuf,nprivlen,NULL,0,&retkey); +rv=bufs2evp("EC","P-256",nprivbuf,nprivlen,NULL,0,&retkey); if (rv==1) { printf("P-256 with just private key worked\n"); } else { @@ -183,7 +184,7 @@ } EVP_PKEY_free(retkey);retkey=NULL; -rv=bufs2evp("X25519",xprivbuf,xprivlen,xpubbuf,xpublen,&retkey); +rv=bufs2evp("X25519",N
Re: OpenSSL 3.0.0 APIs for creating an EVP_PKEY from a p256 private key octet string
On Wed, 2021-03-10 at 00:53 +, Stephen Farrell wrote: > Hiya, > > On 09/03/2021 03:09, Benjamin Kaduk wrote: > > I would have expected that the API should hide the differences > > other than the group name ... but these APIs are still pretty > > new to me, too. If you can point me at your code I might have > > more to say. > > So again it's probably my fault but I'm still not seeing the > same behaviour for NIST and non-NIST curves. I made up what > I hope is a fairly simple bit of test code [1] so that might > help clarify where I'm wrong or (less likely) where a change > in the library might be useful. > > As I build the test code, the p256 cases seem to work, with > or without the public key, but both 25519 cases fail. In my > (still untidy:-) HPKE code EVP_PKEY_new_raw_private_key > for the non-NIST curves works, but not for NIST curves. So I > have an ok workaround, even if the fault's not mine, which > it of course probably is:-) Not sure if there are any other issues, but the public key parameter should be "encoded-pub-key" AFAIK. Tomas Mraz
Re: OpenSSL 3.0.0 APIs for creating an EVP_PKEY from a p256 private key octet string
Hiya, On 09/03/2021 03:09, Benjamin Kaduk wrote: I would have expected that the API should hide the differences other than the group name ... but these APIs are still pretty new to me, too. If you can point me at your code I might have more to say. So again it's probably my fault but I'm still not seeing the same behaviour for NIST and non-NIST curves. I made up what I hope is a fairly simple bit of test code [1] so that might help clarify where I'm wrong or (less likely) where a change in the library might be useful. As I build the test code, the p256 cases seem to work, with or without the public key, but both 25519 cases fail. In my (still untidy:-) HPKE code EVP_PKEY_new_raw_private_key for the non-NIST curves works, but not for NIST curves. So I have an ok workaround, even if the fault's not mine, which it of course probably is:-) Cheers, S. [1] https://github.com/sftcd/happykey/blob/master/test2evp.c OpenPGP_0x5AB2FAF17B172BEA.asc Description: application/pgp-keys OpenPGP_signature Description: OpenPGP digital signature
Re: OpenSSL 3.0.0 APIs for creating an EVP_PKEY from a p256 private key octet string
Hiya, On 09/03/2021 03:09, Benjamin Kaduk wrote: I would have expected that the API should hide the differences other than the group name ... but these APIs are still pretty new to me, too. If you can point me at your code I might have more to say. Will check it out some more, tidy the code up and get back later/tomorrow, Cheers, S. OpenPGP_0x5AB2FAF17B172BEA.asc Description: application/pgp-keys OpenPGP_signature Description: OpenPGP digital signature
Re: OpenSSL 3.0.0 APIs for creating an EVP_PKEY from a p256 private key octet string
On Tue, Mar 09, 2021 at 02:44:20AM +, Stephen Farrell wrote: > > Hiya, > > On 08/03/2021 02:37, Benjamin Kaduk wrote: > > Hi Stephen :) > > > > The API you'll want to use is EVP_PKEY_fromdata(); there's > > a stubbed out example of using it to make an EVP_PKEY with > > EC group parameters at > > https://github.com/openssl/openssl/issues/14258#issuecomment-783351031 > > but the translation to also specify OSSL_PKEY_PARAM_PRIV_KEY > > (and possibly OSSL_PKEY_PARAM_PUB_KEY; I forget if you need > > to pass both) should be fairly straightforward. > > Thanks for that! I worked around a few things and still need > to tidy-up but got things working that way without any more > deprecation warnings. > > > > > Let us know if you run into trouble with that route. > > One outstanding issue is that I still need different code > paths for NIST curves vs. 25519 & 448 - is that just me > (quite likely:-) or should these new APIs hide differences > between those different curves? I would have expected that the API should hide the differences other than the group name ... but these APIs are still pretty new to me, too. If you can point me at your code I might have more to say. -Ben
Re: OpenSSL 3.0.0 APIs for creating an EVP_PKEY from a p256 private key octet string
Hiya, On 08/03/2021 02:37, Benjamin Kaduk wrote: Hi Stephen :) The API you'll want to use is EVP_PKEY_fromdata(); there's a stubbed out example of using it to make an EVP_PKEY with EC group parameters at https://github.com/openssl/openssl/issues/14258#issuecomment-783351031 but the translation to also specify OSSL_PKEY_PARAM_PRIV_KEY (and possibly OSSL_PKEY_PARAM_PUB_KEY; I forget if you need to pass both) should be fairly straightforward. Thanks for that! I worked around a few things and still need to tidy-up but got things working that way without any more deprecation warnings. Let us know if you run into trouble with that route. One outstanding issue is that I still need different code paths for NIST curves vs. 25519 & 448 - is that just me (quite likely:-) or should these new APIs hide differences between those different curves? Thanks again, S. -Ben On Mon, Mar 08, 2021 at 02:23:36AM +, Stephen Farrell wrote: Hiya, My question: how does one setup an EVP_PKEY for a NIST curve (e.g. p256) key pair when one has the private key in an octet string using the latest OpenSSL 3.0.0 high level APIs? I'm trying to get rid of deprecation warnings from my code for HPKE [1] when dealing with NIST curves using the new (I guess?) OSSL_PARAM_* approach. I'm failing at the moment;-) So, given an octet string from a set of test vectors (e.g. [2]) what's the proper way to setup an EVP_PKEY for that to allow one to validate the test vectors? Happy to try produce a stand-alone example for this in the next few days if one doesn't exist (I've not found one so far). Thanks, Stephen. [1] https://github.com/sftcd/happykey/blob/7d52d34c516ab58ca1433004ff82b2a6a82eea4c/hpke.c#L1263 [2] https://github.com/cfrg/draft-irtf-cfrg-hpke pub RSA 4096/7B172BEA 2017-12-22 Stephen Farrell (2017) sub RSA 4096/36CB8BB6 2017-12-22 OpenPGP_0x5AB2FAF17B172BEA.asc Description: application/pgp-keys OpenPGP_signature Description: OpenPGP digital signature
Re: OpenSSL 3.0.0 APIs for creating an EVP_PKEY from a p256 private key octet string
Hi Stephen :) The API you'll want to use is EVP_PKEY_fromdata(); there's a stubbed out example of using it to make an EVP_PKEY with EC group parameters at https://github.com/openssl/openssl/issues/14258#issuecomment-783351031 but the translation to also specify OSSL_PKEY_PARAM_PRIV_KEY (and possibly OSSL_PKEY_PARAM_PUB_KEY; I forget if you need to pass both) should be fairly straightforward. Let us know if you run into trouble with that route. -Ben On Mon, Mar 08, 2021 at 02:23:36AM +, Stephen Farrell wrote: > > Hiya, > > My question: how does one setup an EVP_PKEY for a NIST > curve (e.g. p256) key pair when one has the private key > in an octet string using the latest OpenSSL 3.0.0 high > level APIs? > > I'm trying to get rid of deprecation warnings from my > code for HPKE [1] when dealing with NIST curves using > the new (I guess?) OSSL_PARAM_* approach. I'm failing > at the moment;-) > > So, given an octet string from a set of test vectors > (e.g. [2]) what's the proper way to setup an EVP_PKEY > for that to allow one to validate the test vectors? > > Happy to try produce a stand-alone example for this > in the next few days if one doesn't exist (I've not > found one so far). > > Thanks, > Stephen. > > [1] > https://github.com/sftcd/happykey/blob/7d52d34c516ab58ca1433004ff82b2a6a82eea4c/hpke.c#L1263 > [2] https://github.com/cfrg/draft-irtf-cfrg-hpke pub RSA 4096/7B172BEA 2017-12-22 Stephen Farrell (2017) > sub RSA 4096/36CB8BB6 2017-12-22 >
OpenSSL 3.0.0 APIs for creating an EVP_PKEY from a p256 private key octet string
Hiya, My question: how does one setup an EVP_PKEY for a NIST curve (e.g. p256) key pair when one has the private key in an octet string using the latest OpenSSL 3.0.0 high level APIs? I'm trying to get rid of deprecation warnings from my code for HPKE [1] when dealing with NIST curves using the new (I guess?) OSSL_PARAM_* approach. I'm failing at the moment;-) So, given an octet string from a set of test vectors (e.g. [2]) what's the proper way to setup an EVP_PKEY for that to allow one to validate the test vectors? Happy to try produce a stand-alone example for this in the next few days if one doesn't exist (I've not found one so far). Thanks, Stephen. [1] https://github.com/sftcd/happykey/blob/7d52d34c516ab58ca1433004ff82b2a6a82eea4c/hpke.c#L1263 [2] https://github.com/cfrg/draft-irtf-cfrg-hpke OpenPGP_0x5AB2FAF17B172BEA.asc Description: application/pgp-keys OpenPGP_signature Description: OpenPGP digital signature
Cheking public or private key
Dear All, Is there a way to check if a EVP_PKEY is a public or private key ? In the case of use of EVP_Sign or EVP_DigestSign functions, an application leads to crash with SIGSEGV if an incorrect key is given when finalizing process. Thanks in advance for your answers. Kind regards, Patrice.
encoding/decoding ECX private key with optional public key
Hello, Is there any option either in 1.1.1 or 3.0.0 to encode ECX(x25519, x448, ed25519, ed448) private keys along with optional/implicit public key as specified in https://tools.ietf.org/html/rfc8410#page-7 Is there any plan to provide this support in future? I ask this as I have come across an h/w which generates ecx (private) key, returns reference to the private key and the corresponding public key(octet string). Private key reference instead of actual private key is encoded while storing the key persistently. Public key derived by s/w from this "dummy" private key wouldn't be the correct public key and h/w doesn't have the ability/support to take in the private key reference to generate the public key. This makes saving public key along with private key (reference) unavoidable at the time of key generation. I would like to know how other h/w engines/providers supporting ecx keygen are handling this situation. Thanks, Thulasi.
Sign without having the private key
Hi all, thanks for the input so far. What I have been playing with is something like this: RSA_METHOD *meth = RSA_meth_dup(RSA_get_default_method()); RSA_meth_set1_name(meth, "myrsa"); RSA_meth_set_sign(meth, sign); RSA_meth_set_verify(meth, verify); RSA_set_default_method(meth); with sign and verify being functions that I implemented. But non of these two is ever invoked. If I also set the init and final callbacks, they are properly executed. Any ideas? Br, Timo Von: openssl-users im Auftrag von Dmitry Belyavsky Gesendet: Montag, 11. Januar 2021 19:00 An: openssl-users@openssl.org Betreff: Re: Sign without having the private key Dear Timo, For 1.0* versions it was possible to provide custom RSA_METHOD and EC_METHOD and implement an IPC callback. I think it still should work for 1.1.1 It may be also useful to take a look at the async API. On Mon, Jan 11, 2021 at 6:56 PM Timo Lange mailto:tiolan...@outlook.com>> wrote: Hey all, I have a question similar to http://openssl.6102.n7.nabble.com/private-key-not-available-for-client-cert-cb-td79369.html, that I am actively following, but though it differs in detail. What I want to achieve is the following: My client applications runs inside a container and needs to establish a mutual TLS connection to a server. The client certificate is available in the container. The root certificate, as well as the client private key is not available inside the container, but stored in a HSM. For sure the private key may never leave the HSM and also the root certificate should not. The application cannot directly interfere with the HSM through standardized mechanisms as it is not accessible from inside the container. For doing so a proprietary interprocess-communication is required. I now want something like a "verify callback" and a "sign callback". The "verify callback" would be needed in order to verify the server certificate against the root certificate. It seems to be easy using: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_cert_verify_callback.html I need the same, something like a "sign callback" also for the private key, when a signature is required during handshake. Such that requests from openSSL to sign something can be forwarded through the inter-process-communication into the HSM. So that the actual signing happens there. This would only be required during handshake. For the actual encryption symmetric keys can be used, such that the encryption takes place in the openSSL library, not in the HSM. I assume I need to write a custom ENGINE, but failed with all my approaches. Can someone give me brief hint on where to start and which API to look at first? Thanks a lot! Timo -- SY, Dmitry Belyavsky
RE: private key not available for client_cert_cb
> From: openssl-users On Behalf Of George > Sent: Tuesday, 12 January, 2021 00:18 > I'm running this in Windows 10 and when I load the smart card middleware > PKCS11 DLL, I see the exception: > Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: > unsigned long at memory location 0x07FCFA00. OK. If I were debugging libp11, it would be useful to know what the exception actually was, but as it is all I can say is that it seems to be a libp11 problem. As you noted further below: > It looks like someone else using a smart card has also encountered similar > problems in Windows but there is no real answer as to why they are occurring: > https://www.codeproject.com/Questions/1254182/Smart-card-apis-throw-first-chance- > exceptions-but You'll probably have to just swallow the exceptions and retry until it works or your code decides to give up and return an error. Maybe one of the libp11 maintainers or someone else using the library will dig into it at some point. -- Michael Wojcik
Re: private key not available for client_cert_cb
I'm running this in Windows 10 and when I load the smart card middleware PKCS11 DLL, I see the exception: Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: unsigned long at memory location 0x07FCFA00. During mutual authentication, I also see alot of other exceptions such as: Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. I traced them down to various PKCS11 calls on the card in libp11. e.g. the function call to C_GetSlotList(...) in the file p11_slot.c triggers an exception: int pkcs11_enumerate_slots(PKCS11_CTX *ctx, PKCS11_SLOT **slotp, unsigned int *countp) { . . . *rv = cpriv->method->C_GetSlotList(FALSE, NULL_PTR, &nslots);* . . . } It is interesting to note that this function seems to get called multiple times and it eventually works. I do not fully understand how/why the code does that and if this is the design intent. The exceptions don't seem to have any effect on the functionality, but I still need to understand why they are occurring. It looks like someone else using a smart card has also encountered similar problems in Windows but there is no real answer as to why they are occurring: https://www.codeproject.com/Questions/1254182/Smart-card-apis-throw-first-chance-exceptions-but Thanks, George On 2021-01-11 9:41 a.m., Michael Wojcik wrote: From: openssl-users On Behalf Of George Sent: Sunday, 10 January, 2021 21:01 Right now I am using the "libp11" DLL (i.e. libp11-libp11-0.4.11\src\pkcs11.dll) with my PKCS11 smart card middleware DLL. Should I be using the OpenSC pkcs11 DLL instead of my middleware DLL if I am using libp1? Honestly, I have no idea. It's been years since I worked with PKCS#11, and then I was using a single piece of test hardware. I got it working with OpenSSL using the OpenSC modules, but that may have been specific to my case. Do you know if it is normal to see exceptions related to the PKCS11 function calls in the libp11 code? For example, I can see the following function generate an exception on C_GetSlotList(...) multiple times but it eventually is successful. Is this normal behaviour? What sort of "exception"? A Windows exception? UNIX signal? C++ exception? My initial guess would be that this is a timing issue - maybe the device needs some time to become available, for example. But that's just a guess. Maybe someone with more experience with a variety of HSMs and PKCS#11 will weigh in. -- Michael Wojcik
Re: private key not available for client_cert_cb
I found out what my problem is! I'm running it in FIPS mode and this causes the PKCS11 engine to fail during mutual authentication. I eventually traced the problem to the following issue: https://bugzilla.redhat.com/show_bug.cgi?id=1827535 It looks like there is a bug in libp11. Once I made the suggested workaround, it worked. My original code, which is based on https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c worked perfectly after I added in the libp11 fix. :) Thanks! George On 2021-01-11 11:01 a.m., Jan Just Keijser wrote: Hi, On 08/01/21 22:35, George wrote: Hi, I have been trying to setup mutual authentication using a smart card but I can't seem to get the OpenSSL Engine to send a response back to the server containing client's certificate from the smart card. I'm using the following to configure the certificate and private key: ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0); SSL_CTX_use_certificate(sslContext, cert_info.cert); EVP_PKEY* privateKey = ENGINE_load_private_key(engine, "2b2586c684d69b670c0a805edf514e720f2b757d8e2faa0b3a7ff23d1ccfc7ba", transfer_pin, &cb_data); SSL_CTX_use_PrivateKey(sslContext, privateKey); (I have been using the code in https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c as a guide.) This seems be successful. However, when I start the mutual authentication with SSL_connect(ssl) , the mutual authentications handshake fails. I can see the server requesting the certificate from the client and the client sends back an ACK for this message. However, the client does not send the certificate to the server. I was looking through the OpenSSL code openssl-1.0.2u\ssl\ssl_rsa.c and noticed something interesting. The comment indicates that the flag *RSA_METHOD_FLAG_NO_CHECK* should be set for smart cards: static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) { . . . #ifndef OPENSSL_NO_RSA * /*** ** * Don't check the public/private key, this is mostly for smart** ** * cards.** ** */* if ((pkey->type == EVP_PKEY_RSA) && (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ; else #endif . . . } However, it is not actually set when I use a debugger to inspect the flag. Does it need to be set? If so, how is this done? I could not find anything related to this in https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c if you read through the code blob that Michael pointed you to, you will find that this flag needs to be set *under certain circumstances* when using smartcards. It has to do mostly with the situation where - private key is on the smart card - the public key/certificate is NOT on the smart card - you ask OpenSSL to verify the private key without explicitly providing a public key. I've never run into this issue, but then again, I have not tested very often the case where the certificate was not present on the HSM/smart card but the private key is. YMMV. As for using pksc11helper versus using libp11: that is just a matter of taste. I used the engine_pkcs11 + libp11 route for the eap-tls code , mostly because it was the first "working" set of tools I found at the time. You can also take the "pkcs11helper" route, which is what OpenVPN does (see https://github.com/openvpn). Both methods have pro's and con's. Do you run into problems if you DO not set the RSA_METHOD_FLAG_NO_CHECK flag? All that flag does is to stop OpenSSL from verifying that a public key/cert and private key match/belong together for RSA keys only; if your smartcard supports EC keys then this flag will do you no good. HTH, JJK
RE: Sign without having the private key
> From: openssl-users On Behalf Of Timo > Lange > Sent: Monday, 11 January, 2021 10:56 > The root certificate, as well as the client private key is not available > inside > the container, but stored in a HSM. > For sure the private key may never leave the HSM OK. > and also the root certificate should not. This doesn't make any sense. Certificates are not sensitive data, and it's inconvenient, if not impossible (depending on application software and HSM firmware) to split certificate chain validation across the host machine and the HSM. Using the HSM as a certificate trust anchor *store* might make sense, depending on the use case. But the certificate would have to be extracted from the HSM by the application at runtime and made available to OpenSSL (or whatever's handling chain validation) so the peer's entity certificate can be verified. > The application cannot directly interfere with the HSM through standardized > mechanisms > as it is not accessible from inside the container. > For doing so a proprietary interprocess-communication is required. That certainly seems like unnecessary complexity, but I'll assume there's some valid justification for it. > I assume I need to write a custom ENGINE, but failed with all my approaches. You *could* write a custom engine, which you'd then have to rewrite as a custom provider when support for OpenSSL 1.1.1 ends and you need to move to OpenSSL 3.0 or its successor. However, you could also hide your IPC mechanism under a PKCS#11 implementation, and just use OpenSSL's PKCS#11 engine. PKCS#11 is the standard mechanism for talking to an HSM, and nothing says it can't involve IPC in the middle. That is: OpenSSL -> pkcs11 engine -> your IPC client (written as a PKCS#11 library) -> some communications channel -> your IPC server -> real PKCS#11 library for your HSM. You could implement the IPC client and server using an open-source PKCS#11 shim such as pkcs11-helper. This area has been discussed recently on this list. However, now you have the problem of securing the IPC channel. This is an architecture I'd be reluctant to endorse, given the complexity and attack surface. -- Michael Wojcik
Re: Sign without having the private key
Dear Timo, For 1.0* versions it was possible to provide custom RSA_METHOD and EC_METHOD and implement an IPC callback. I think it still should work for 1.1.1 It may be also useful to take a look at the async API. On Mon, Jan 11, 2021 at 6:56 PM Timo Lange wrote: > Hey all, > > I have a question similar to > http://openssl.6102.n7.nabble.com/private-key-not-available-for-client-cert-cb-td79369.html, > that I am actively following, but though it differs in detail. > > What I want to achieve is the following: > My client applications runs inside a container and needs to establish a > mutual TLS connection to a server. > The client certificate is available in the container. > The root certificate, as well as the client private key is not available > inside the container, but stored in a HSM. > For sure the private key may never leave the HSM and also the root > certificate should not. > > The application cannot directly interfere with the HSM through > standardized mechanisms as it is not accessible from inside the container. > For doing so a proprietary interprocess-communication is required. > > I now want something like a "verify callback" and a "sign callback". > > The "verify callback" would be needed in order to verify the server > certificate against the root certificate. It seems to be easy using: > https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_cert_verify_callback.html > > I need the same, something like a "sign callback" also for the private > key, when a signature is required during handshake. Such that requests from > openSSL to sign something can be forwarded through the > inter-process-communication into the HSM. So that the actual signing > happens there. > This would only be required during handshake. For the actual encryption > symmetric keys can be used, such that the encryption takes place in the > openSSL library, not in the HSM. > > I assume I need to write a custom ENGINE, but failed with all my > approaches. > > Can someone give me brief hint on where to start and which API to look at > first? > > Thanks a lot! > Timo > > -- SY, Dmitry Belyavsky
Sign without having the private key
Hey all, I have a question similar to http://openssl.6102.n7.nabble.com/private-key-not-available-for-client-cert-cb-td79369.html, that I am actively following, but though it differs in detail. What I want to achieve is the following: My client applications runs inside a container and needs to establish a mutual TLS connection to a server. The client certificate is available in the container. The root certificate, as well as the client private key is not available inside the container, but stored in a HSM. For sure the private key may never leave the HSM and also the root certificate should not. The application cannot directly interfere with the HSM through standardized mechanisms as it is not accessible from inside the container. For doing so a proprietary interprocess-communication is required. I now want something like a "verify callback" and a "sign callback". The "verify callback" would be needed in order to verify the server certificate against the root certificate. It seems to be easy using: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_cert_verify_callback.html I need the same, something like a "sign callback" also for the private key, when a signature is required during handshake. Such that requests from openSSL to sign something can be forwarded through the inter-process-communication into the HSM. So that the actual signing happens there. This would only be required during handshake. For the actual encryption symmetric keys can be used, such that the encryption takes place in the openSSL library, not in the HSM. I assume I need to write a custom ENGINE, but failed with all my approaches. Can someone give me brief hint on where to start and which API to look at first? Thanks a lot! Timo
Re: private key not available for client_cert_cb
Hi, On 08/01/21 22:35, George wrote: Hi, I have been trying to setup mutual authentication using a smart card but I can't seem to get the OpenSSL Engine to send a response back to the server containing client's certificate from the smart card. I'm using the following to configure the certificate and private key: ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0); SSL_CTX_use_certificate(sslContext, cert_info.cert); EVP_PKEY* privateKey = ENGINE_load_private_key(engine, "2b2586c684d69b670c0a805edf514e720f2b757d8e2faa0b3a7ff23d1ccfc7ba", transfer_pin, &cb_data); SSL_CTX_use_PrivateKey(sslContext, privateKey); (I have been using the code in https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c as a guide.) This seems be successful. However, when I start the mutual authentication with SSL_connect(ssl) , the mutual authentications handshake fails. I can see the server requesting the certificate from the client and the client sends back an ACK for this message. However, the client does not send the certificate to the server. I was looking through the OpenSSL code openssl-1.0.2u\ssl\ssl_rsa.c and noticed something interesting. The comment indicates that the flag *RSA_METHOD_FLAG_NO_CHECK* should be set for smart cards: static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) { . . . #ifndef OPENSSL_NO_RSA * /*** ** * Don't check the public/private key, this is mostly for smart** ** * cards.** ** */* if ((pkey->type == EVP_PKEY_RSA) && (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ; else #endif . . . } However, it is not actually set when I use a debugger to inspect the flag. Does it need to be set? If so, how is this done? I could not find anything related to this in https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c if you read through the code blob that Michael pointed you to, you will find that this flag needs to be set *under certain circumstances* when using smartcards. It has to do mostly with the situation where - private key is on the smart card - the public key/certificate is NOT on the smart card - you ask OpenSSL to verify the private key without explicitly providing a public key. I've never run into this issue, but then again, I have not tested very often the case where the certificate was not present on the HSM/smart card but the private key is. YMMV. As for using pksc11helper versus using libp11: that is just a matter of taste. I used the engine_pkcs11 + libp11 route for the eap-tls code , mostly because it was the first "working" set of tools I found at the time. You can also take the "pkcs11helper" route, which is what OpenVPN does (see https://github.com/openvpn). Both methods have pro's and con's. Do you run into problems if you DO not set the RSA_METHOD_FLAG_NO_CHECK flag? All that flag does is to stop OpenSSL from verifying that a public key/cert and private key match/belong together for RSA keys only; if your smartcard supports EC keys then this flag will do you no good. HTH, JJK
RE: private key not available for client_cert_cb
> From: openssl-users On Behalf Of George > Sent: Sunday, 10 January, 2021 21:01 > Right now I am using the "libp11" DLL (i.e. > libp11-libp11-0.4.11\src\pkcs11.dll) > with my PKCS11 smart card middleware DLL. Should I be using the OpenSC pkcs11 > DLL > instead of my middleware DLL if I am using libp1? Honestly, I have no idea. It's been years since I worked with PKCS#11, and then I was using a single piece of test hardware. I got it working with OpenSSL using the OpenSC modules, but that may have been specific to my case. > Do you know if it is normal to see exceptions related to the PKCS11 function > calls > in the libp11 code? For example, I can see the following function generate an > exception on C_GetSlotList(...) multiple times but it eventually is > successful. > Is this normal behaviour? What sort of "exception"? A Windows exception? UNIX signal? C++ exception? My initial guess would be that this is a timing issue - maybe the device needs some time to become available, for example. But that's just a guess. Maybe someone with more experience with a variety of HSMs and PKCS#11 will weigh in. -- Michael Wojcik
Re: private key not available for client_cert_cb
Hi, I had a look at the pkcs11-helper and can see where the RSA_METHOD_FLAG_NO_CHECK is being set. It's using a session object called pkcs11h_openssl_session_t, which I do not see in the libp11 or openSC code. Right now I am using the "libp11" DLL (i.e. libp11-libp11-0.4.11\src\pkcs11.dll) with my PKCS11 smart card middleware DLL. Should I be using the OpenSC pkcs11 DLL instead of my middleware DLL if I am using libp1? Do you know if it is normal to see exceptions related to the PKCS11 function calls in the libp11 code? For example, I can see the following function generate an exception on C_GetSlotList(...) multiple times but it eventually is successful. Is this normal behaviour? int pkcs11_enumerate_slots(PKCS11_CTX *ctx, PKCS11_SLOT **slotp, unsigned int *countp) { . . . rv = cpriv->method->C_GetSlotList(FALSE, NULL_PTR, &nslots); . . . } Thanks, George On 2021-01-08 6:32 p.m., Michael Wojcik wrote: From: openssl-users On Behalf Of George Sent: Friday, 8 January, 2021 14:35 The comment indicates that the flag RSA_METHOD_FLAG_NO_CHECK should be set for smart cards[...] However, it is not actually set when I use a debugger to inspect the flag. Does it need to be set? If so, how is this done? If memory serves, the PKCS#11 implementation invoked by the pkcs11 engine is supposed to set it. See for example this patch to OpenSC's pkcs11-helper library: https://github.com/OpenSC/pkcs11-helper/commit/5198bb1e557dfd4109bea41c086825bf6ebdd9f3 (That patch actually is to set a different flag, but it shows the code in question.) I know, that's probably not terribly helpful. If you do a web search for something like pkcs11 "RSA_METHOD_FLAG_NO_CHECK" you'll probably find a number of hits where other people ran into similar problems. Isn't PKCS#11 grand? If you're bored with all the interoperability problems of X.509, PKIX, and TLS, we have good news! -- Michael Wojcik
RE: private key not available for client_cert_cb
> From: openssl-users On Behalf Of George > Sent: Friday, 8 January, 2021 14:35 > The comment indicates that the flag RSA_METHOD_FLAG_NO_CHECK should be set > for smart cards[...] > However, it is not actually set when I use a debugger to inspect the flag. > Does it need to be set? If so, how is this done? If memory serves, the PKCS#11 implementation invoked by the pkcs11 engine is supposed to set it. See for example this patch to OpenSC's pkcs11-helper library: https://github.com/OpenSC/pkcs11-helper/commit/5198bb1e557dfd4109bea41c086825bf6ebdd9f3 (That patch actually is to set a different flag, but it shows the code in question.) I know, that's probably not terribly helpful. If you do a web search for something like pkcs11 "RSA_METHOD_FLAG_NO_CHECK" you'll probably find a number of hits where other people ran into similar problems. Isn't PKCS#11 grand? If you're bored with all the interoperability problems of X.509, PKIX, and TLS, we have good news! -- Michael Wojcik
Re: private key not available for client_cert_cb
Hi, I have been trying to setup mutual authentication using a smart card but I can't seem to get the OpenSSL Engine to send a response back to the server containing client's certificate from the smart card. I'm using the following to configure the certificate and private key: ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0); SSL_CTX_use_certificate(sslContext, cert_info.cert); EVP_PKEY* privateKey = ENGINE_load_private_key(engine, "2b2586c684d69b670c0a805edf514e720f2b757d8e2faa0b3a7ff23d1ccfc7ba", transfer_pin, &cb_data); SSL_CTX_use_PrivateKey(sslContext, privateKey); (I have been using the code in https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c as a guide.) This seems be successful. However, when I start the mutual authentication with SSL_connect(ssl) , the mutual authentications handshake fails. I can see the server requesting the certificate from the client and the client sends back an ACK for this message. However, the client does not send the certificate to the server. I was looking through the OpenSSL code openssl-1.0.2u\ssl\ssl_rsa.c and noticed something interesting. The comment indicates that the flag *RSA_METHOD_FLAG_NO_CHECK* should be set for smart cards: static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) { . . . #ifndef OPENSSL_NO_RSA * /*** ** * Don't check the public/private key, this is mostly for smart** ** * cards.** ** */* if ((pkey->type == EVP_PKEY_RSA) && (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ; else #endif . . . } However, it is not actually set when I use a debugger to inspect the flag. Does it need to be set? If so, how is this done? I could not find anything related to this in https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c Thanks, George On 2021-01-05 11:51 a.m., Jan Just Keijser wrote: Hi, On 05/01/21 07:39, George wrote: Hi, I was looking at the code in https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c and realized I forgot to call ENGINE_ctrl_cmd(...) to setup "LOAD_CERT_CTRL". However, when I do this, the callback function is no longer being called during the mutual authentication handshake. I'm wondering if I have the parameter "cert_info.s_slot_cert_id" incorrectly configured. Here is what my code looks like: struct { const char* s_slot_cert_id; X509* cert; } cert_info; *cert_info.s_slot_cert_id = "a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45";* cert_info.cert = NULL; *ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0);* *SSL_CTX_use_certificate(sslContext, cert_info.cert);* I tried manually using LOAD_CERT_CTRL in the openssl shell but I cannot seem to get it to work and cannot find any examples of how to use it. Is the syntax for *LOAD_CERT_CTRL* correct? I am using***"LOAD_CERT_CTRL:".* OpenSSL> engine - -t dynamic -pre "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre "MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll" -pre PIN:123456 -pre FORCE_LOGIN *-pre "LOAD_CERT_CTRL:a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45" *(dynamic) Dynamic engine loading support [Success]: SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll [Success]: ID:pkcs11 [Success]: LIST_ADD:1 [Success]: LOAD [Success]: MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll [Success]: PIN:123456 [Success]: FORCE_LOGIN *[Failure]: LOAD_CERT_CTRL:a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45** **4196:error:260AB086:engine routines:ENGINE_ctrl_cmd_string:cmd not executable:.\crypto\engine\eng_ctrl.c:316:* Loaded: (pkcs11) pkcs11 engine [ available ] SO_PATH: Specifies the path to the 'pkcs11' engine shared library (input flags): STRING MODULE_PATH: Specifies the path to the PKCS#11 module shared library (input flags): STRING PIN: Specifies the pin code (input flags): STRING VERBOSE: Print additional details (input flags): NO_INPUT QUIET: Remove additional details (input flags): NO_INPUT *LOAD_CERT_CTRL: Get the certificate from card** ** (input flags): [Internal]* INIT_ARGS: Specifies additional initialization arguments to the PKCS#11 module (input flags): STRING SET_USER_INTERFACE: Set the global user interface (internal) (input flags): [Internal] SET_CALLBACK_DATA: Set the global user i
Re: private key not available for client_cert_cb
Hi, On 05/01/21 07:39, George wrote: Hi, I was looking at the code in https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c and realized I forgot to call ENGINE_ctrl_cmd(...) to setup "LOAD_CERT_CTRL". However, when I do this, the callback function is no longer being called during the mutual authentication handshake. I'm wondering if I have the parameter "cert_info.s_slot_cert_id" incorrectly configured. Here is what my code looks like: struct { const char* s_slot_cert_id; X509* cert; } cert_info; *cert_info.s_slot_cert_id = "a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45";* cert_info.cert = NULL; *ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0);* *SSL_CTX_use_certificate(sslContext, cert_info.cert);* I tried manually using LOAD_CERT_CTRL in the openssl shell but I cannot seem to get it to work and cannot find any examples of how to use it. Is the syntax for *LOAD_CERT_CTRL* correct? I am using***"LOAD_CERT_CTRL:".* OpenSSL> engine - -t dynamic -pre "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre "MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll" -pre PIN:123456 -pre FORCE_LOGIN *-pre "LOAD_CERT_CTRL:a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45" *(dynamic) Dynamic engine loading support [Success]: SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll [Success]: ID:pkcs11 [Success]: LIST_ADD:1 [Success]: LOAD [Success]: MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll [Success]: PIN:123456 [Success]: FORCE_LOGIN *[Failure]: LOAD_CERT_CTRL:a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45** **4196:error:260AB086:engine routines:ENGINE_ctrl_cmd_string:cmd not executable:.\crypto\engine\eng_ctrl.c:316:* Loaded: (pkcs11) pkcs11 engine [ available ] SO_PATH: Specifies the path to the 'pkcs11' engine shared library (input flags): STRING MODULE_PATH: Specifies the path to the PKCS#11 module shared library (input flags): STRING PIN: Specifies the pin code (input flags): STRING VERBOSE: Print additional details (input flags): NO_INPUT QUIET: Remove additional details (input flags): NO_INPUT *LOAD_CERT_CTRL: Get the certificate from card** ** (input flags): [Internal]* INIT_ARGS: Specifies additional initialization arguments to the PKCS#11 module (input flags): STRING SET_USER_INTERFACE: Set the global user interface (internal) (input flags): [Internal] SET_CALLBACK_DATA: Set the global user interface extra data (internal) (input flags): [Internal] FORCE_LOGIN: Force login to the PKCS#11 module (input flags): NO_INPUT OpenSSL> I'm using the certificate object ID "a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45" for LOAD_CERT_CTRL. Is this right? (I also tried adding "0:" in front of it to indicate slot 0, but that did not work either. this has little to do with OpenSSL at the moment and more with libp11 - perhaps someone more knowledgable on the libp11 mailing list can help you. I'd try to use -post LOAD_CERT_CTRL instead of '-pre', as you want this done after the engine has been loaded. The cert ID does look OK. Note that if you want to use the s_client command that you canNOT specify the certificate form '-certform engine' as the code does not grok that. HTH, JJK
Re: private key not available for client_cert_cb
Hi, I was looking at the code in https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c and realized I forgot to call ENGINE_ctrl_cmd(...) to setup "LOAD_CERT_CTRL". However, when I do this, the callback function is no longer being called during the mutual authentication handshake. I'm wondering if I have the parameter "cert_info.s_slot_cert_id" incorrectly configured. Here is what my code looks like: struct { const char* s_slot_cert_id; X509* cert; } cert_info; *cert_info.s_slot_cert_id = "a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45";* cert_info.cert = NULL; *ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0);* *SSL_CTX_use_certificate(sslContext, cert_info.cert);* I tried manually using LOAD_CERT_CTRL in the openssl shell but I cannot seem to get it to work and cannot find any examples of how to use it. Is the syntax for *LOAD_CERT_CTRL* correct? I am using***"LOAD_CERT_CTRL:".* OpenSSL> engine - -t dynamic -pre "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre "MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll" -pre PIN:123456 -pre FORCE_LOGIN *-pre "LOAD_CERT_CTRL:a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45" *(dynamic) Dynamic engine loading support [Success]: SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll [Success]: ID:pkcs11 [Success]: LIST_ADD:1 [Success]: LOAD [Success]: MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll [Success]: PIN:123456 [Success]: FORCE_LOGIN *[Failure]: LOAD_CERT_CTRL:a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45** **4196:error:260AB086:engine routines:ENGINE_ctrl_cmd_string:cmd not executable:.\crypto\engine\eng_ctrl.c:316:* Loaded: (pkcs11) pkcs11 engine [ available ] SO_PATH: Specifies the path to the 'pkcs11' engine shared library (input flags): STRING MODULE_PATH: Specifies the path to the PKCS#11 module shared library (input flags): STRING PIN: Specifies the pin code (input flags): STRING VERBOSE: Print additional details (input flags): NO_INPUT QUIET: Remove additional details (input flags): NO_INPUT *LOAD_CERT_CTRL: Get the certificate from card** ** (input flags): [Internal]* INIT_ARGS: Specifies additional initialization arguments to the PKCS#11 module (input flags): STRING SET_USER_INTERFACE: Set the global user interface (internal) (input flags): [Internal] SET_CALLBACK_DATA: Set the global user interface extra data (internal) (input flags): [Internal] FORCE_LOGIN: Force login to the PKCS#11 module (input flags): NO_INPUT OpenSSL> I'm using the certificate object ID "a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45" for LOAD_CERT_CTRL. Is this right? (I also tried adding "0:" in front of it to indicate slot 0, but that did not work either. C:\Program Files\OpenSC Project\OpenSC\tools>pkcs11-tool --module="C:\Program Files\HID Global\ActivClient/acpkcs211.dll" -l -O Using slot 0 with a present token (0x0) . . . Certificate Object; type = X.509 cert label: Card Authentication - PIVKey E7F4FBE4644BA647ADDBE261BE596757 subject: DN: CN=PIVKey E7F4FBE4644BA647ADDBE261BE596757 *ID: a9bee4d72100c52f77c3fc288d2be01a34b5d44f91b3b7ea3d349b8a25752c45* Thanks, George On 2020-12-23 6:00 a.m., Jan Just Keijser wrote: Hi, On 20/12/20 09:39, George wrote: Hi, I tried running the "s_client" command and it appears to be working. I guess there must be something wrong in my code. it is good news that the s_client command is working - it means there is something wrong with your code but you have everything at hand to fix it: download the openssl 1.0.2 tarball / zip file and look for the files apps/s_client.c apps/apps.c that contains all of the code that the 's_client' command uses to make a connection and my bet is that is also does not call ENGINE_init My crash occurs when I call ENGINE_init(pkey_engine); I notice your code does not call this function. Is this needed needed? If so, when/where should it be called? tbh, I don't know - look through the openssl sources to see what it does, exactly. What exactly is the definition of "pkey_identifier" in ENGINE_load_private_key(pkey_engine, *pkey_identifier*, transfer_pin, &cb_data) ? I'm not clear on what th
Re: private key not available for client_cert_cb
Hi, On 20/12/20 09:39, George wrote: Hi, I tried running the "s_client" command and it appears to be working. I guess there must be something wrong in my code. it is good news that the s_client command is working - it means there is something wrong with your code but you have everything at hand to fix it: download the openssl 1.0.2 tarball / zip file and look for the files apps/s_client.c apps/apps.c that contains all of the code that the 's_client' command uses to make a connection and my bet is that is also does not call ENGINE_init My crash occurs when I call ENGINE_init(pkey_engine); I notice your code does not call this function. Is this needed needed? If so, when/where should it be called? tbh, I don't know - look through the openssl sources to see what it does, exactly. What exactly is the definition of "pkey_identifier" in ENGINE_load_private_key(pkey_engine, *pkey_identifier*, transfer_pin, &cb_data) ? I'm not clear on what this value should be. Can you give an example of what it would look like? I have the following on my smart card: Private Key Object; RSA label: Authentication - * *ID:**2b2586c684d69b670c0a805edf514e720f2b757d8e2faa0b3a7ff23d1ccfc7ba* Usage: unwrap Access: sensitive, never extractable Allowed mechanisms: RSA-PKCS,RSA-X-509 Would the *pkey_identifier* be the *ID* in the above? yes, although if you have multiple smartcards inserted at the same time then it helps to add the slot number, e.g. 0: What exactly is "prompt_info" in the structure PW_CB_DATA? i.e. typedef struct pw_cb_data { const void* password; const char* *prompt_info;* } PW_CB_DATA; Can you give an example of what it might look like? Is the value of cb_data populated by the transfer_pin callback functions, or should it already contain a value when ENGINE_load_private_key is called? Is there a way to skip the callback transfer_pin and use a hard coded pin for test purposes when calling ENGINE_load_private_key(...)? my eap-tls code does just that: if the password is specified in the ppp config file then the user is not prompted: if (pkey_engine) { EVP_PKEY *pkey = NULL; PW_CB_DATA cb_data; UI_METHOD* transfer_pin = NULL; cb_data.password = passwd; cb_data.prompt_info = pkey_identifier; HTH, JJK On 2020-12-19 8:05 p.m., Jan Just Keijser wrote: I'd say no engine/pkcs11 module should trigger exceptions - that's an error in the pkcs11 module. Something you can try is this: run the 'openssl.exe' command: openssl engine -t dynamic -pre "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre "MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll" then on the OpenSSL prompt , try s_client -keyform engine -key 0: -cert "clientcert.pem" -connect remote_host:remote_port that should start a TLS connection and use the pcks11 engine to ask for the key , identified by in slot 0 (adjust the slot number if your smart card starts at number 1 etc. HTH, JJK
Re: private key not available for client_cert_cb
Hi, I tried running the "s_client" command and it appears to be working. I guess there must be something wrong in my code. My crash occurs when I call ENGINE_init(pkey_engine); I notice your code does not call this function. Is this needed needed? If so, when/where should it be called? What exactly is the definition of "pkey_identifier" in ENGINE_load_private_key(pkey_engine, *pkey_identifier*, transfer_pin, &cb_data) ? I'm not clear on what this value should be. Can you give an example of what it would look like? I have the following on my smart card: Private Key Object; RSA label: Authentication - * *ID:**2b2586c684d69b670c0a805edf514e720f2b757d8e2faa0b3a7ff23d1ccfc7ba* Usage: unwrap Access: sensitive, never extractable Allowed mechanisms: RSA-PKCS,RSA-X-509 Would the *pkey_identifier* be the *ID* in the above? What exactly is "prompt_info" in the structure PW_CB_DATA? i.e. typedef struct pw_cb_data { const void* password; const char* *prompt_info;* } PW_CB_DATA; Can you give an example of what it might look like? Is the value of cb_data populated by the transfer_pin callback functions, or should it already contain a value when ENGINE_load_private_key is called? Is there a way to skip the callback transfer_pin and use a hard coded pin for test purposes when calling ENGINE_load_private_key(...)? Thanks! George On 2020-12-19 8:05 p.m., Jan Just Keijser wrote: I'd say no engine/pkcs11 module should trigger exceptions - that's an error in the pkcs11 module. Something you can try is this: run the 'openssl.exe' command: openssl engine -t dynamic -pre "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre "MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll" then on the OpenSSL prompt , try s_client -keyform engine -key 0: -cert "clientcert.pem" -connect remote_host:remote_port that should start a TLS connection and use the pcks11 engine to ask for the key , identified by in slot 0 (adjust the slot number if your smart card starts at number 1 etc. HTH, JJK
Re: private key not available for client_cert_cb
Hi, On 19/12/20 04:48, George wrote: Hi, I narrowed the problem down to ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL) This causes the initial exception Exception thrown at 0x757346D2 in GENCom.exe: Microsoft C++ exception: unsigned long at memory location 0x006FCD68. It looks like some of the Engine methods cause an exception, but not all of them: * Works:* ENGINE_METHOD_CIPHERS ENGINE_METHOD_DIGESTS ENGINE_METHOD_DSA ENGINE_METHOD_DH ENGINE_METHOD_RAND ENGINE_METHOD_PKEY_ASN1_METHS *Causes An Exception:* ENGINE_METHOD_RSA ENGINE_METHOD_ECDH ENGINE_METHOD_ECDSA ENGINE_METHOD_PKEY_METHS Is that normal behaviour, or is something wrong? Is there a way to find the supported engine methods to avoid triggering an exception? I'd say no engine/pkcs11 module should trigger exceptions - that's an error in the pkcs11 module. Something you can try is this: run the 'openssl.exe' command: openssl engine -t dynamic -pre "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre "MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll" then on the OpenSSL prompt , try s_client -keyform engine -key 0: -cert "clientcert.pem" -connect remote_host:remote_port that should start a TLS connection and use the pcks11 engine to ask for the key , identified by in slot 0 (adjust the slot number if your smart card starts at number 1 etc. HTH, JJK It seems like alot of other smaple code I have looked at calls ENGINE_init(pkey_engine); Is the needed? When I call it, it always returns with "0". Should it be returning with "1"? I did some testing in the OpenSSL command line, and here is what I found: - The command line "speed" test appears to be fine: OpenSSL> speed -engine pkcs11 engine "pkcs11" set. Doing mdc2 for 3s on 16 size blocks: 2688737 mdc2's in 2.98s Doing mdc2 for 3s on 64 size blocks: 880529 mdc2's in 3.00s Doing mdc2 for 3s on 256 size blocks: 240916 mdc2's in 2.98s Doing mdc2 for 3s on 1024 size blocks: 61287 mdc2's in 3.00s Doing mdc2 for 3s on 8192 size blocks: 7774 mdc2's in 2.98s . . . - I also tried the following, which successfully created the PEM files: OpenSSL> req -engine pkcs11 -new -key "pkcs11:object=Authentication - *;type=private;pin-value=123456" -keyform engine -out req2.pem -text -x509 -subj "/CN=*" OpenSSL> x509 -engine pkcs11 -signkey "pkcs11:object=Authentication - *;type=private;pin-value=123456" -keyform engine -in req2.pem -out cert2.pem Thanks, George On 2020-12-18 3:40 a.m., Jan Just Keijser wrote: Hi, On 18/12/20 06:21, George wrote: Hi, I'm able to setup the engine now, but as soon as I attempt to execute the command ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL); ,I see all kinds of middleware exceptions being generated: Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: unsigned long at memory location 0x07FCFA00. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. . . . Do you have any idea what is causing these errors? Am I missing something in the configuration? When I use the OpenSSL command line debugger, there are no errors: OpenSSL> engine -t dynamic -pre "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre "MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll" (dynamic) Dynamic engine loading support [Success]: SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll [Success]: ID:pkcs11 [Success]: LIST_ADD:1 [Success]: LOAD [Success]: MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll Loaded: (pkcs11) pkcs11 engine [ available ] OpenSSL> Here is what my simplified code looks like: char* enginePluginLibrary = "C:\\Users\\whipp\\j
Re: private key not available for client_cert_cb
Hi, I narrowed the problem down to ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL) This causes the initial exception Exception thrown at 0x757346D2 in GENCom.exe: Microsoft C++ exception: unsigned long at memory location 0x006FCD68. It looks like some of the Engine methods cause an exception, but not all of them: * Works:* ENGINE_METHOD_CIPHERS ENGINE_METHOD_DIGESTS ENGINE_METHOD_DSA ENGINE_METHOD_DH ENGINE_METHOD_RAND ENGINE_METHOD_PKEY_ASN1_METHS *Causes An Exception:* ENGINE_METHOD_RSA ENGINE_METHOD_ECDH ENGINE_METHOD_ECDSA ENGINE_METHOD_PKEY_METHS Is that normal behaviour, or is something wrong? Is there a way to find the supported engine methods to avoid triggering an exception? It seems like alot of other smaple code I have looked at calls ENGINE_init(pkey_engine); Is the needed? When I call it, it always returns with "0". Should it be returning with "1"? I did some testing in the OpenSSL command line, and here is what I found: - The command line "speed" test appears to be fine: OpenSSL> speed -engine pkcs11 engine "pkcs11" set. Doing mdc2 for 3s on 16 size blocks: 2688737 mdc2's in 2.98s Doing mdc2 for 3s on 64 size blocks: 880529 mdc2's in 3.00s Doing mdc2 for 3s on 256 size blocks: 240916 mdc2's in 2.98s Doing mdc2 for 3s on 1024 size blocks: 61287 mdc2's in 3.00s Doing mdc2 for 3s on 8192 size blocks: 7774 mdc2's in 2.98s . . . - I also tried the following, which successfully created the PEM files: OpenSSL> req -engine pkcs11 -new -key "pkcs11:object=Authentication - *;type=private;pin-value=123456" -keyform engine -out req2.pem -text -x509 -subj "/CN=*" OpenSSL> x509 -engine pkcs11 -signkey "pkcs11:object=Authentication - *;type=private;pin-value=123456" -keyform engine -in req2.pem -out cert2.pem Thanks, George On 2020-12-18 3:40 a.m., Jan Just Keijser wrote: Hi, On 18/12/20 06:21, George wrote: Hi, I'm able to setup the engine now, but as soon as I attempt to execute the command ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL); ,I see all kinds of middleware exceptions being generated: Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: unsigned long at memory location 0x07FCFA00. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. . . . Do you have any idea what is causing these errors? Am I missing something in the configuration? When I use the OpenSSL command line debugger, there are no errors: OpenSSL> engine -t dynamic -pre "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre "MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll" (dynamic) Dynamic engine loading support [Success]: SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll [Success]: ID:pkcs11 [Success]: LIST_ADD:1 [Success]: LOAD [Success]: MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll Loaded: (pkcs11) pkcs11 engine [ available ] OpenSSL> Here is what my simplified code looks like: char* enginePluginLibrary = "C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll"; char* pkcs11MiddlewareLibrary = "C:\\Program Files (x86)\\HID Global\\ActivClient\\acpkcs211.dll"; ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); ENGINE *pkey_engine = ENGINE_by_id("dynamic"); ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", enginePluginLibrary, 0); ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0); ENGINE_ctrl_cmd_string(pkey_engine, "LIST_ADD", "1", 0); ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0); ENGINE_ctrl_cmd_string(pkey_engine, "MODULE_PATH", pkcs11MiddlewareLibrary, 0); ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL); main difference between the OPENSSL.EXE example and your code is that last call: here's wat "ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL)" does: int ENG
Re: private key not available for client_cert_cb
Hi, On 18/12/20 06:21, George wrote: Hi, I'm able to setup the engine now, but as soon as I attempt to execute the command ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL); ,I see all kinds of middleware exceptions being generated: Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: unsigned long at memory location 0x07FCFA00. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. . . . Do you have any idea what is causing these errors? Am I missing something in the configuration? When I use the OpenSSL command line debugger, there are no errors: OpenSSL> engine -t dynamic -pre "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre "MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll" (dynamic) Dynamic engine loading support [Success]: SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll [Success]: ID:pkcs11 [Success]: LIST_ADD:1 [Success]: LOAD [Success]: MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll Loaded: (pkcs11) pkcs11 engine [ available ] OpenSSL> Here is what my simplified code looks like: char* enginePluginLibrary = "C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll"; char* pkcs11MiddlewareLibrary = "C:\\Program Files (x86)\\HID Global\\ActivClient\\acpkcs211.dll"; ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); ENGINE *pkey_engine = ENGINE_by_id("dynamic"); ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", enginePluginLibrary, 0); ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0); ENGINE_ctrl_cmd_string(pkey_engine, "LIST_ADD", "1", 0); ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0); ENGINE_ctrl_cmd_string(pkey_engine, "MODULE_PATH", pkcs11MiddlewareLibrary, 0); ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL); main difference between the OPENSSL.EXE example and your code is that last call: here's wat "ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL)" does: int ENGINE_set_default(ENGINE *e, unsigned int flags) { if ((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e)) return 0; if ((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e)) return 0; #ifndef OPENSSL_NO_RSA if ((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e)) return 0; #endif #ifndef OPENSSL_NO_DSA if ((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e)) return 0; #endif #ifndef OPENSSL_NO_DH if ((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e)) return 0; #endif #ifndef OPENSSL_NO_ECDH if ((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e)) return 0; #endif #ifndef OPENSSL_NO_ECDSA if ((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e)) return 0; #endif if ((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e)) return 0; if ((flags & ENGINE_METHOD_PKEY_METHS) && !ENGINE_set_default_pkey_meths(e)) return 0; if ((flags & ENGINE_METHOD_PKEY_ASN1_METHS) && !ENGINE_set_default_pkey_asn1_meths(e)) return 0; return 1; } (from the openssl 1.0.2 source tree) It could be that one of those methods is not throwing the errors with your smart card. I'd advise you to test your smart card capabilities . It might also be useful to do more command line testing with your smartcard using engine - -t dynamic -pre "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre "MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll" and then try out certain operations, like encrypt/decrypt or simply use the command speed and watch for any errors - that should give you a hint which method is not supported by your smart card. HTH, JJK On 2020-12-17 8:39 p.m., Jan Just Keijser wrote: On 17/12/20 14:55, George wrote: Ok. So I use the li
Re: private key not available for client_cert_cb
Hi, I'm able to setup the engine now, but as soon as I attempt to execute the command ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL); ,I see all kinds of middleware exceptions being generated: Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: unsigned long at memory location 0x07FCFA00. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. Exception thrown at 0x773046D2 in GENCom.exe: Microsoft C++ exception: AI::Middleware::CMWException at memory location 0x032FD2D0. . . . Do you have any idea what is causing these errors? Am I missing something in the configuration? When I use the OpenSSL command line debugger, there are no errors: OpenSSL> engine -t dynamic -pre "SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll" -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre "MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll" (dynamic) Dynamic engine loading support [Success]: SO_PATH:C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll [Success]: ID:pkcs11 [Success]: LIST_ADD:1 [Success]: LOAD [Success]: MODULE_PATH:C:\Program Files (x86)\HID Global\ActivClient\\acpkcs211.dll Loaded: (pkcs11) pkcs11 engine [ available ] OpenSSL> Here is what my simplified code looks like: char* enginePluginLibrary = "C:\\Users\\whipp\\junk4\\libp11-libp11-0.4.11\\src\\pkcs11.dll"; char* pkcs11MiddlewareLibrary = "C:\\Program Files (x86)\\HID Global\\ActivClient\\acpkcs211.dll"; ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); ENGINE *pkey_engine = ENGINE_by_id("dynamic"); ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", enginePluginLibrary, 0); ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0); ENGINE_ctrl_cmd_string(pkey_engine, "LIST_ADD", "1", 0); ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0); ENGINE_ctrl_cmd_string(pkey_engine, "MODULE_PATH", pkcs11MiddlewareLibrary, 0); ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL); Thanks! George On 2020-12-17 8:39 p.m., Jan Just Keijser wrote: On 17/12/20 14:55, George wrote: Ok. So I use the libp11 project DLL file for the SO_PATH and my smart card middleware DLL for the MODULE_PATH when setting up the OpenSSL Engine? yes just like in the example I posted below. I would recommend the p11 wiki page to do it using the command line first - much easier to test & debug. JJK
Re: private key not available for client_cert_cb
On 17/12/20 14:55, George wrote: Ok. So I use the libp11 project DLL file for the SO_PATH and my smart card middleware DLL for the MODULE_PATH when setting up the OpenSSL Engine? yes just like in the example I posted below. I would recommend the p11 wiki page to do it using the command line first - much easier to test & debug. JJK On 2020-12-17 3:22 a.m., Jan Just Keijser wrote: Hi, On 16/12/20 20:26, George wrote: Hi, I've been looking at the code in the pppd EAP-TLS patch, but I can't seem to load the engine with the pkcs11 DLL. It is failing with the error: error:2507606A:DSO support routines:WIN32_BIND_FUNC:could not bind to the requested symbol name I've verified the path is correct. I am using OpenSSL1.0.2u with the FIPS Object Module 2.0.16 in Windows 10. Do I need to do anything special to allow loading of DLLs in OpenSSL? Here is what I am trying to do: char* engine_name = "C:\\Users\\whipp\\junk4\\ActivClient\\acpkcs211.dll"; ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); ENGINE *pkey_engine = ENGINE_by_id("dynamic"); ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", engine_name, 0); ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0); ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0); Do you see anything wrong with this? I forgot to mention that loading a PKCS11 driver from within OpenSSL is a 2 stage rocket: first stage: load the engine_pkcs11 module using char* engine_name = "|C:\\Windows\\System32\\pkcs11.dll"| This is a separate piece of code and is part of the libp11 project: https://github.com/OpenSC/libp11 (it also has a nice wiki that explains how to do it on the command line using OPENSSL.EXE) Then create an openssl.cnf section like this: |openssl_conf = openssl_init [openssl_init] engines = engine_section [engine_section] pkcs11 = pkcs11_section [pkcs11_section] engine_id = pkcs11 dynamic_path = "C:\Windows\System32\opensc-pkcs11.dll" MODULE_path = "||C:\Users\whipp\junk4\ActivClient\acpkcs211.dll" PIN = "0001password" init = 0| and load that (see the EAP-TLS code for an example or read https://stackoverflow.com/questions/41119744/pkcs11-engine-for-openssl for a similar question). HTH, JJK On 2020-12-15 4:38 a.m., Jan Just Keijser wrote: Hi, On 14/12/20 21:01, George wrote: Ok, so I am not actually going to populate EVP_PKEY with a private key in the callback function: int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)? Instead, I will call EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); to get the EVP_PKEY, which will be used by OpenSSL to access the Smart Card. Once I get the resulting EVP_PKEY using ENGINE_load_private_key(...), how do I assign it to pkey in the callback function? If I had private key I would use something like EVP_PKEY_assign_RSA(..) Since I don't actually have a private key, should I use something else? like Michael pointed out, my eap-tls code is just an example of how you could handle a pkcs11 device; it does not us a callback at all, but my code loads the client cert+key upfront and avoids having to use a client callback altogether. I guess you could also use a client callback for this (perhaps in combination with SSL_CTX_set_client_cert_engine()) . In that case you would get the (pseudo) key from the engine like this EVP_PKEY *engine_key = ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); and then set pkey = &engine_key; and see if that works. Note that the ENGINE_load_private_key() function *does* return a EVP_PKEY struct but that does not mean the entire private key is contained in it; a private key consists of a modulus and a private part (exponent, prime1, prime2, exponent1, exponent2 etc). the ENGINE_load_private_key() call will return a struct containing the modulus but not the rest. You then use the engine to do the actual encryption and decryption. HTH, JJK
Re: private key not available for client_cert_cb
Ok. So I use the libp11 project DLL file for the SO_PATH and my smart card middleware DLL for the MODULE_PATH when setting up the OpenSSL Engine? Thanks, George On 2020-12-17 3:22 a.m., Jan Just Keijser wrote: Hi, On 16/12/20 20:26, George wrote: Hi, I've been looking at the code in the pppd EAP-TLS patch, but I can't seem to load the engine with the pkcs11 DLL. It is failing with the error: error:2507606A:DSO support routines:WIN32_BIND_FUNC:could not bind to the requested symbol name I've verified the path is correct. I am using OpenSSL1.0.2u with the FIPS Object Module 2.0.16 in Windows 10. Do I need to do anything special to allow loading of DLLs in OpenSSL? Here is what I am trying to do: char* engine_name = "C:\\Users\\whipp\\junk4\\ActivClient\\acpkcs211.dll"; ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); ENGINE *pkey_engine = ENGINE_by_id("dynamic"); ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", engine_name, 0); ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0); ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0); Do you see anything wrong with this? I forgot to mention that loading a PKCS11 driver from within OpenSSL is a 2 stage rocket: first stage: load the engine_pkcs11 module using char* engine_name = "|C:\\Windows\\System32\\pkcs11.dll"| This is a separate piece of code and is part of the libp11 project: https://github.com/OpenSC/libp11 (it also has a nice wiki that explains how to do it on the command line using OPENSSL.EXE) Then create an openssl.cnf section like this: |openssl_conf = openssl_init [openssl_init] engines = engine_section [engine_section] pkcs11 = pkcs11_section [pkcs11_section] engine_id = pkcs11 dynamic_path = "C:\Windows\System32\opensc-pkcs11.dll" MODULE_path = "||C:\Users\whipp\junk4\ActivClient\acpkcs211.dll" PIN = "0001password" init = 0| and load that (see the EAP-TLS code for an example or read https://stackoverflow.com/questions/41119744/pkcs11-engine-for-openssl for a similar question). HTH, JJK On 2020-12-15 4:38 a.m., Jan Just Keijser wrote: Hi, On 14/12/20 21:01, George wrote: Ok, so I am not actually going to populate EVP_PKEY with a private key in the callback function: int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)? Instead, I will call EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); to get the EVP_PKEY, which will be used by OpenSSL to access the Smart Card. Once I get the resulting EVP_PKEY using ENGINE_load_private_key(...), how do I assign it to pkey in the callback function? If I had private key I would use something like EVP_PKEY_assign_RSA(..) Since I don't actually have a private key, should I use something else? like Michael pointed out, my eap-tls code is just an example of how you could handle a pkcs11 device; it does not us a callback at all, but my code loads the client cert+key upfront and avoids having to use a client callback altogether. I guess you could also use a client callback for this (perhaps in combination with SSL_CTX_set_client_cert_engine()) . In that case you would get the (pseudo) key from the engine like this EVP_PKEY *engine_key = ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); and then set pkey = &engine_key; and see if that works. Note that the ENGINE_load_private_key() function *does* return a EVP_PKEY struct but that does not mean the entire private key is contained in it; a private key consists of a modulus and a private part (exponent, prime1, prime2, exponent1, exponent2 etc). the ENGINE_load_private_key() call will return a struct containing the modulus but not the rest. You then use the engine to do the actual encryption and decryption. HTH, JJK
Re: private key not available for client_cert_cb
Hi, On 16/12/20 20:26, George wrote: Hi, I've been looking at the code in the pppd EAP-TLS patch, but I can't seem to load the engine with the pkcs11 DLL. It is failing with the error: error:2507606A:DSO support routines:WIN32_BIND_FUNC:could not bind to the requested symbol name I've verified the path is correct. I am using OpenSSL1.0.2u with the FIPS Object Module 2.0.16 in Windows 10. Do I need to do anything special to allow loading of DLLs in OpenSSL? Here is what I am trying to do: char* engine_name = "C:\\Users\\whipp\\junk4\\ActivClient\\acpkcs211.dll"; ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); ENGINE *pkey_engine = ENGINE_by_id("dynamic"); ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", engine_name, 0); ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0); ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0); Do you see anything wrong with this? I forgot to mention that loading a PKCS11 driver from within OpenSSL is a 2 stage rocket: first stage: load the engine_pkcs11 module using char* engine_name = "|C:\\Windows\\System32\\pkcs11.dll"| This is a separate piece of code and is part of the libp11 project: https://github.com/OpenSC/libp11 (it also has a nice wiki that explains how to do it on the command line using OPENSSL.EXE) Then create an openssl.cnf section like this: |openssl_conf = openssl_init [openssl_init] engines = engine_section [engine_section] pkcs11 = pkcs11_section [pkcs11_section] engine_id = pkcs11 dynamic_path = "C:\Windows\System32\opensc-pkcs11.dll" MODULE_path = "||C:\Users\whipp\junk4\ActivClient\acpkcs211.dll" PIN = "0001password" init = 0| and load that (see the EAP-TLS code for an example or read https://stackoverflow.com/questions/41119744/pkcs11-engine-for-openssl for a similar question). HTH, JJK On 2020-12-15 4:38 a.m., Jan Just Keijser wrote: Hi, On 14/12/20 21:01, George wrote: Ok, so I am not actually going to populate EVP_PKEY with a private key in the callback function: int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)? Instead, I will call EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); to get the EVP_PKEY, which will be used by OpenSSL to access the Smart Card. Once I get the resulting EVP_PKEY using ENGINE_load_private_key(...), how do I assign it to pkey in the callback function? If I had private key I would use something like EVP_PKEY_assign_RSA(..) Since I don't actually have a private key, should I use something else? like Michael pointed out, my eap-tls code is just an example of how you could handle a pkcs11 device; it does not us a callback at all, but my code loads the client cert+key upfront and avoids having to use a client callback altogether. I guess you could also use a client callback for this (perhaps in combination with SSL_CTX_set_client_cert_engine()) . In that case you would get the (pseudo) key from the engine like this EVP_PKEY *engine_key = ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); and then set pkey = &engine_key; and see if that works. Note that the ENGINE_load_private_key() function *does* return a EVP_PKEY struct but that does not mean the entire private key is contained in it; a private key consists of a modulus and a private part (exponent, prime1, prime2, exponent1, exponent2 etc). the ENGINE_load_private_key() call will return a struct containing the modulus but not the rest. You then use the engine to do the actual encryption and decryption. HTH, JJK
Re: private key not available for client_cert_cb
Hi, I've been looking at the code in the pppd EAP-TLS patch, but I can't seem to load the engine with the pkcs11 DLL. It is failing with the error: error:2507606A:DSO support routines:WIN32_BIND_FUNC:could not bind to the requested symbol name I've verified the path is correct. I am using OpenSSL1.0.2u with the FIPS Object Module 2.0.16 in Windows 10. Do I need to do anything special to allow loading of DLLs in OpenSSL? Here is what I am trying to do: char* engine_name = "C:\\Users\\whipp\\junk4\\ActivClient\\acpkcs211.dll"; ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); ENGINE *pkey_engine = ENGINE_by_id("dynamic"); ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", engine_name, 0); ENGINE_ctrl_cmd_string(pkey_engine, "ID", "pkcs11", 0); ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0); Do you see anything wrong with this? Thanks, George On 2020-12-15 4:38 a.m., Jan Just Keijser wrote: Hi, On 14/12/20 21:01, George wrote: Ok, so I am not actually going to populate EVP_PKEY with a private key in the callback function: int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)? Instead, I will call EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); to get the EVP_PKEY, which will be used by OpenSSL to access the Smart Card. Once I get the resulting EVP_PKEY using ENGINE_load_private_key(...), how do I assign it to pkey in the callback function? If I had private key I would use something like EVP_PKEY_assign_RSA(..) Since I don't actually have a private key, should I use something else? like Michael pointed out, my eap-tls code is just an example of how you could handle a pkcs11 device; it does not us a callback at all, but my code loads the client cert+key upfront and avoids having to use a client callback altogether. I guess you could also use a client callback for this (perhaps in combination with SSL_CTX_set_client_cert_engine()) . In that case you would get the (pseudo) key from the engine like this EVP_PKEY *engine_key = ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); and then set pkey = &engine_key; and see if that works. Note that the ENGINE_load_private_key() function *does* return a EVP_PKEY struct but that does not mean the entire private key is contained in it; a private key consists of a modulus and a private part (exponent, prime1, prime2, exponent1, exponent2 etc). the ENGINE_load_private_key() call will return a struct containing the modulus but not the rest. You then use the engine to do the actual encryption and decryption. HTH, JJK
Re: private key not available for client_cert_cb
Hi, On 14/12/20 21:01, George wrote: Ok, so I am not actually going to populate EVP_PKEY with a private key in the callback function: int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)? Instead, I will call EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); to get the EVP_PKEY, which will be used by OpenSSL to access the Smart Card. Once I get the resulting EVP_PKEY using ENGINE_load_private_key(...), how do I assign it to pkey in the callback function? If I had private key I would use something like EVP_PKEY_assign_RSA(..) Since I don't actually have a private key, should I use something else? like Michael pointed out, my eap-tls code is just an example of how you could handle a pkcs11 device; it does not us a callback at all, but my code loads the client cert+key upfront and avoids having to use a client callback altogether. I guess you could also use a client callback for this (perhaps in combination with SSL_CTX_set_client_cert_engine()) . In that case you would get the (pseudo) key from the engine like this EVP_PKEY *engine_key = ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); and then set pkey = &engine_key; and see if that works. Note that the ENGINE_load_private_key() function *does* return a EVP_PKEY struct but that does not mean the entire private key is contained in it; a private key consists of a modulus and a private part (exponent, prime1, prime2, exponent1, exponent2 etc). the ENGINE_load_private_key() call will return a struct containing the modulus but not the rest. You then use the engine to do the actual encryption and decryption. HTH, JJK Thanks, George On 2020-12-14 12:59 p.m., Michael Wojcik wrote: You can't get the private key from the smartcard. Instead, you have to let the engine do the encryption. I don't know what ENGINE_load_private_key actually does - in my PKCS#11 work I didn't have to get into this - but I suspect it just puts a key identifier into pkey. Then what ought to happen is that you pass that pkey to OpenSSL where you need an EVP_PKEY, and OpenSSL will call the engine's appropriate method for whatever it needs to do, and the engine will tell the smartcard "do this thing using the key with this identifier". I suggest you refer to a example such as the PPP code that Jan cited to see how it does this sort of thing. Or you can take the approach that Paul suggests in his reply of writing your own engine specifically for your hardware, if you don't need generic PKCS#11 support. Basically, PKCS#11 gives you support for more devices, and in principle should do some of the work for you; but as Paul suggests, the PKCS#11 API and its dependence on external drivers and libraries means it's not easy to work with. In some cases where you only need to support one type of device (or a family of devices that all use the same driver / library) it might well be easier to just write a simple engine that only supports the features you need. You can use the source for the existing engines in OpenSSL to get an idea of what that looks like. A few years back I forked the OpenSSL CAPI engine to make some fixes and enhancements, and that was pretty straightforward. So if you have a well-documented API for your particular smartcard, with handy functions like "do this to get an RSA signature of a blob of data with this key ID and these parameters", you may want to try Paul's route. Really depends on your requirements and what kind of support you already have for your device. And all of this changes in 3.0 with the new "provider" architecture, so you'll get to take another crack at it soon. -- Michael Wojcik
RE: private key not available for client_cert_cb
> From: openssl-users On Behalf Of George > Sent: Monday, 14 December, 2020 13:01 > Once I get the resulting EVP_PKEY using ENGINE_load_private_key(...), > how do I assign it to pkey in the callback function? I don't know offhand. As I said in my other message, that's not an area I had to get into when I was working with PKCS#11 some years ago. My advice is to look at existing examples, such as the code Jan pointed you to. -- Michael Wojcik
Re: private key not available for client_cert_cb
Ok, so I am not actually going to populate EVP_PKEY with a private key in the callback function: int (*client_cert_cb)(SSL *ssl, X509 **x509, *EVP_PKEY **pkey*)? Instead, I will call EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); to get the EVP_PKEY, which will be used by OpenSSL to access the Smart Card. Once I get the resulting EVP_PKEY using ENGINE_load_private_key(...), how do I assign it to pkey in the callback function? If I had private key I would use something like EVP_PKEY_assign_RSA(..) Since I don't actually have a private key, should I use something else? Thanks, George On 2020-12-14 12:59 p.m., Michael Wojcik wrote: You can't get the private key from the smartcard. Instead, you have to let the engine do the encryption. I don't know what ENGINE_load_private_key actually does - in my PKCS#11 work I didn't have to get into this - but I suspect it just puts a key identifier into pkey. Then what ought to happen is that you pass that pkey to OpenSSL where you need an EVP_PKEY, and OpenSSL will call the engine's appropriate method for whatever it needs to do, and the engine will tell the smartcard "do this thing using the key with this identifier". I suggest you refer to a example such as the PPP code that Jan cited to see how it does this sort of thing. Or you can take the approach that Paul suggests in his reply of writing your own engine specifically for your hardware, if you don't need generic PKCS#11 support. Basically, PKCS#11 gives you support for more devices, and in principle should do some of the work for you; but as Paul suggests, the PKCS#11 API and its dependence on external drivers and libraries means it's not easy to work with. In some cases where you only need to support one type of device (or a family of devices that all use the same driver / library) it might well be easier to just write a simple engine that only supports the features you need. You can use the source for the existing engines in OpenSSL to get an idea of what that looks like. A few years back I forked the OpenSSL CAPI engine to make some fixes and enhancements, and that was pretty straightforward. So if you have a well-documented API for your particular smartcard, with handy functions like "do this to get an RSA signature of a blob of data with this key ID and these parameters", you may want to try Paul's route. Really depends on your requirements and what kind of support you already have for your device. And all of this changes in 3.0 with the new "provider" architecture, so you'll get to take another crack at it soon. -- Michael Wojcik
RE: private key not available for client_cert_cb
> From: openssl-users On Behalf Of George > Sent: Monday, 14 December, 2020 09:36 > I see what you mean. So once I have everything setup, i use the following > to get the private key: > EVP_PKEY *pkey = ENGINE_load_private_key(...); > > Will pkey actually contain the private key from the smart card? It had better not. > I thought it was not possible to get a private key from a smart card? That's the point of the smartcard (or other HSM), yes. > Once I have pkey, do I simply use it within the client_cert_cb callback > function? You can't get the private key from the smartcard. Instead, you have to let the engine do the encryption. I don't know what ENGINE_load_private_key actually does - in my PKCS#11 work I didn't have to get into this - but I suspect it just puts a key identifier into pkey. Then what ought to happen is that you pass that pkey to OpenSSL where you need an EVP_PKEY, and OpenSSL will call the engine's appropriate method for whatever it needs to do, and the engine will tell the smartcard "do this thing using the key with this identifier". I suggest you refer to a example such as the PPP code that Jan cited to see how it does this sort of thing. Or you can take the approach that Paul suggests in his reply of writing your own engine specifically for your hardware, if you don't need generic PKCS#11 support. Basically, PKCS#11 gives you support for more devices, and in principle should do some of the work for you; but as Paul suggests, the PKCS#11 API and its dependence on external drivers and libraries means it's not easy to work with. In some cases where you only need to support one type of device (or a family of devices that all use the same driver / library) it might well be easier to just write a simple engine that only supports the features you need. You can use the source for the existing engines in OpenSSL to get an idea of what that looks like. A few years back I forked the OpenSSL CAPI engine to make some fixes and enhancements, and that was pretty straightforward. So if you have a well-documented API for your particular smartcard, with handy functions like "do this to get an RSA signature of a blob of data with this key ID and these parameters", you may want to try Paul's route. Really depends on your requirements and what kind of support you already have for your device. And all of this changes in 3.0 with the new "provider" architecture, so you'll get to take another crack at it soon. -- Michael Wojcik
Re: private key not available for client_cert_cb
How I did this: 1) You can make up your own EVP_PKEY that uses your own engine implementation and attach a data ptr to it EVP_PKEY* returnPKey; returnPKey = EVP_PKEY_new(); if( returnPKey ) { ENGINE* engine = ENGINE_by_id(YOUR_ENGINE_ID); RSA* sc_rsa = RSA_new_method(engine); if( sc_rsa ) { // attach a reference to a structure holding your smart card middleware info RSA_set_ex_data(sc_rsa, ENGINE_smartcard_rsa_idx_middleware(), (void*)middleware->handle); EVP_PKEY* pk = X509_get_pubkey( returnCert ); if( pk ) { sc_rsa->e = BN_new(); sc_rsa->n = BN_new(); BN_copy(sc_rsa->e, pk->pkey.rsa->e); BN_copy(sc_rsa->n, pk->pkey.rsa->n); EVP_PKEY_free(pk); EVP_PKEY_set1_RSA(returnPKey, sc_rsa); RSA_free(sc_rsa); *outCert = make this X509 from your smart card certificate; *outpkey = returnPKey; } else LogError("smartcards_fetch_identity can't get pubkey\n"); } Then for your engine you will need some methods to configure it as follows: void ENGINE_load_smartcard_keychain(void); /* * ENGINE_tss_keychain_rsa_idx_middleware returns a ex_data index where engine user should store the * pointer to the info needed to use the middleware */ int ENGINE_smartcard_rsa_idx_middleware(void); Your ENGINE_load_smartcard_keychain method should set global values that get returned by ENGINE_smartcard_rsa_idx_middleware: gMiddlewareRSAIndex = RSA_get_ex_new_index(0x1234, NULL, NULL, NULL, NULL); Configure your engine filling in an RSA_METHOD structure with what you will need. You don’t really need all the methods in RSA_METHOD structure, and if you don’t need them add a stub that returns a 0. I did not need either of the mod_exp method or the public key encrypt and decrypt methods. I also did not need the verify or keygen methods. Your init and finish methods just need to return 1. I set the RSA_METHOD flags to RSA_FLAG_FIPS_METHOD|RSA_METHOD_FLAG_NO_CHECK|RSA_FLAG_CACHE_PUBLIC This leaves the cipher methods for private key encrypt/decrypt and sign. The private key methods will be where all the work is done. Write a function to perform the smartcard ‘crypt’ method and use it in private encrypt/decrypt and the signing methods. You will need to pay attention to padding and make sure you know how to pad for PKCS1 type 1. The RSA_SSLV23_PADDING is not required and you can just return an error if you get called with this. I handle the PIN entry requirement by having the engine return a specific error if the PIN is needed, then handle the PIN entry in the application. Once the PIN is entered and available to the middleware, I retry the connection. The trick is to get a pointer to your middleware implementation from the private key engine methods like this: my_middleware_handle = (my_middleware_handle)RSA_get_ex_data(rsa, gMiddlewareRSAIndex); I found that writing the engine was more straightforward that attempting to use PKCS11. > On Dec 14, 2020, at 1:08 AM, George wrote: > > Hi, > >I'm new to OpenSSL and am trying to set up mutual authentication in a > client. The client is setup with OpenSSL 1.0.2u. and the client's certificate > + private key is stored on a Smart Card. When the client receives a > certificate request from the server during the mutual authentication > handshake, the OpenSSL client_cert_cb callback function is automatically > invoked. The problem is that client_cert_cb requires a private key. > Unfortunately, it is not possible to get a private key from a Smart Card. Is > there a way to send a certificate to the server without needing the private > key? > > I'm setting up the callback function with: > > void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, > X509 **x509, EVP_PKEY **pkey)); > > > Here is a sample of what my code looks like when I set this up: > > SSL_CTX_set_client_cert_cb(context, openSSLClientAuthenticationCallBack); &g
Re: private key not available for client_cert_cb
Hi Michael, I see what you mean. So once I have everything setup, i use the following to get the private key: EVP_PKEY *pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, transfer_pin, &cb_data); Will pkey actually contain the private key from the smart card? I thought it was not possible to get a private key from a smart card? Once I have pkey, do I simply use it within the /client_cert_cb/ callback function? Thanks, George On 2020-12-14 10:58 a.m., Michael Wojcik wrote: From: openssl-users On Behalf Of George Sent: Monday, 14 December, 2020 08:15 Thanks for your response. It looks like I don't already have the PPP and PPPD. You don't need PPP to use a smartcard or other PKCS#11 device. Jan just mentioned the source as a exemplar of the interactions your code will need to have with OpenSSL. Are there any other ways to get the Smart Card to work without needing to install additional software? Probably not. OpenSSL's PKCS#11 Engine implements the PKCS#11 API. That API needs a way to talk to the particular PKCS#11-compatible hardware you're using. That means it needs a driver, and generally some configuration as well. It's been a few years since I last played around with this - I got OpenSSL working with a NitroKey as part of a code-signing spike - but you'll need to investigate PKCS#11 support for your particular device. There are Open Source projects such as OpenSC which may give you part or all of what you need to get OpenSSL's PKCS#11 Engine working with your hardware. When I did it, it wasn't trivial. I spent a couple of days on investigation and experimenting before I got anything working, and a couple more days making sure I understood the entire process and documenting procedures that worked consistently. (With some applications I had persistent problems such as Windows insisting on prompting for the device PIN instead of letting me supply it programmatically, but I think that was only when using Microsoft APIs rather than going through OpenSSL.) If the client certificate uses a public key that corresponds to a private key on the smartcard, though, that's what you'll have to do. You can't use a certificate as a proof of identity without the corresponding private key. (Some HSMs and other crypto devices have support for exporting private keys, often as multiple shares, for backup and cloning purposes. Using that to get the private key for direct use defeats the whole purpose of an HSM, of course, so that shouldn't be used to bypass the card.) -- Michael Wojcik
RE: private key not available for client_cert_cb
> From: openssl-users On Behalf Of George > Sent: Monday, 14 December, 2020 08:15 > Thanks for your response. It looks like I don't already have the PPP and > PPPD. You don't need PPP to use a smartcard or other PKCS#11 device. Jan just mentioned the source as a exemplar of the interactions your code will need to have with OpenSSL. > Are there any other ways to get the Smart Card to work without needing to > install additional software? Probably not. OpenSSL's PKCS#11 Engine implements the PKCS#11 API. That API needs a way to talk to the particular PKCS#11-compatible hardware you're using. That means it needs a driver, and generally some configuration as well. It's been a few years since I last played around with this - I got OpenSSL working with a NitroKey as part of a code-signing spike - but you'll need to investigate PKCS#11 support for your particular device. There are Open Source projects such as OpenSC which may give you part or all of what you need to get OpenSSL's PKCS#11 Engine working with your hardware. When I did it, it wasn't trivial. I spent a couple of days on investigation and experimenting before I got anything working, and a couple more days making sure I understood the entire process and documenting procedures that worked consistently. (With some applications I had persistent problems such as Windows insisting on prompting for the device PIN instead of letting me supply it programmatically, but I think that was only when using Microsoft APIs rather than going through OpenSSL.) If the client certificate uses a public key that corresponds to a private key on the smartcard, though, that's what you'll have to do. You can't use a certificate as a proof of identity without the corresponding private key. (Some HSMs and other crypto devices have support for exporting private keys, often as multiple shares, for backup and cloning purposes. Using that to get the private key for direct use defeats the whole purpose of an HSM, of course, so that shouldn't be used to bypass the card.) -- Michael Wojcik
Re: private key not available for client_cert_cb
Hi Jan, Thanks for your response. It looks like I don't already have the PPP and PPPD. Do I need to download and install the following? https://github.com/jjkeijser/ppp/tree/eap-tls I am using OpenSSL in Windows 10 and compiled it with Visual Studio 2019. Will this EAP-TLS code compile/work with Visual Studio in Windows? Are there any other ways to get the Smart Card to work without needing to install additional software? Thanks! George On 2020-12-14 3:51 a.m., Jan Just Keijser wrote: Hi, On 14/12/20 08:08, George wrote: Hi, I'm new to OpenSSL and am trying to set up mutual authentication in a client. The client is setup with OpenSSL 1.0.2u. and the client's certificate + private key is stored on a Smart Card. When the client receives a certificate request from the server during the mutual authentication handshake, the OpenSSL /client_cert_cb/ callback function is automatically invoked. The problem is that /client_cert_cb/ requires a private key. Unfortunately, it is not possible to get a private key from a Smart Card. Is there a way to send a certificate to the server without needing the private key? I'm setting up the callback function with: void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); Here is a sample of what my code looks like when I set this up: SSL_CTX_set_client_cert_cb(context, *openSSLClientAuthenticationCallBack*); int *openSSLClientAuthenticationCallBack*(SSL *ssl, X509 **x509, EVP_PKEY **pkey) { . . . } I can access the Smart Card using the PKCS#11 interface and I'm able to get the certificate and sign it, etc. However, I cannot get the actual private key from the Smart Card. Does anyone know how I can get around this problem? to use a pkcs#11 smartcard you normally use the OpenSSL pkcs11 engine ; you then do something like: engine_name = "pkcs11"; ENGINE_register_all_complete(); pkey_engine = ENGINE_by_id( "dynamic" ); if (pkey_engine) { if (!ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", engine_name, 0) || !ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0)) { warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name ); log_ssl_errors(); ENGINE_free(e); pkey_engine = NULL; } } } if (pkey_engine) { if(!ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL)) } pkey_engine = eaptls_ssl_load_engine( "pkcs11" ); pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, transfer_pin, &cb_data); SSL_CTX_use_PrivateKey(ctx, pkey); where "transfer_pin" is a callback UI function to query the user for the pkcs11 device password. More detailed code can be found in my pppd EAP-TLS patch, file eap-tls.c at https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c (and search for pkey_engine) HTH, JJK
Re: private key not available for client_cert_cb
Hi, On 14/12/20 08:08, George wrote: Hi, I'm new to OpenSSL and am trying to set up mutual authentication in a client. The client is setup with OpenSSL 1.0.2u. and the client's certificate + private key is stored on a Smart Card. When the client receives a certificate request from the server during the mutual authentication handshake, the OpenSSL /client_cert_cb/ callback function is automatically invoked. The problem is that /client_cert_cb/ requires a private key. Unfortunately, it is not possible to get a private key from a Smart Card. Is there a way to send a certificate to the server without needing the private key? I'm setting up the callback function with: void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); Here is a sample of what my code looks like when I set this up: SSL_CTX_set_client_cert_cb(context, *openSSLClientAuthenticationCallBack*); int *openSSLClientAuthenticationCallBack*(SSL *ssl, X509 **x509, EVP_PKEY **pkey) { . . . } I can access the Smart Card using the PKCS#11 interface and I'm able to get the certificate and sign it, etc. However, I cannot get the actual private key from the Smart Card. Does anyone know how I can get around this problem? to use a pkcs#11 smartcard you normally use the OpenSSL pkcs11 engine ; you then do something like: engine_name = "pkcs11"; ENGINE_register_all_complete(); pkey_engine = ENGINE_by_id( "dynamic" ); if (pkey_engine) { if (!ENGINE_ctrl_cmd_string(pkey_engine, "SO_PATH", engine_name, 0) || !ENGINE_ctrl_cmd_string(pkey_engine, "LOAD", NULL, 0)) { warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name ); log_ssl_errors(); ENGINE_free(e); pkey_engine = NULL; } } } if (pkey_engine) { if(!ENGINE_set_default(pkey_engine, ENGINE_METHOD_ALL)) } pkey_engine = eaptls_ssl_load_engine( "pkcs11" ); pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, transfer_pin, &cb_data); SSL_CTX_use_PrivateKey(ctx, pkey); where "transfer_pin" is a callback UI function to query the user for the pkcs11 device password. More detailed code can be found in my pppd EAP-TLS patch, file eap-tls.c at https://github.com/jjkeijser/ppp/blob/eap-tls/pppd/eap-tls.c (and search for pkey_engine) HTH, JJK
private key not available for client_cert_cb
Hi, I'm new to OpenSSL and am trying to set up mutual authentication in a client. The client is setup with OpenSSL 1.0.2u. and the client's certificate + private key is stored on a Smart Card. When the client receives a certificate request from the server during the mutual authentication handshake, the OpenSSL /client_cert_cb/ callback function is automatically invoked. The problem is that /client_cert_cb/ requires a private key. Unfortunately, it is not possible to get a private key from a Smart Card. Is there a way to send a certificate to the server without needing the private key? I'm setting up the callback function with: void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); Here is a sample of what my code looks like when I set this up: SSL_CTX_set_client_cert_cb(context, *openSSLClientAuthenticationCallBack*); int *openSSLClientAuthenticationCallBack*(SSL *ssl, X509 **x509, EVP_PKEY **pkey) { . . . } I can access the Smart Card using the PKCS#11 interface and I'm able to get the certificate and sign it, etc. However, I cannot get the actual private key from the Smart Card. Does anyone know how I can get around this problem? Thanks, George
Re: TLS with Client Authentication using private key from Windows store
Hi Ferenc, On 23/11/20 13:03, Ferenc Gerlits via openssl-users wrote: Hi, I am trying to use openssl to implement a client-side TLS connection with Client Authentication on Windows, using a non-exportable private key stored in the Windows Certificate Store. Currently, our code can use a private key stored in a local file, and if the key in the Windows store was exportable, I could export it and use it in the existing code. But the key is non-exportable, which is a problem. Does anyone know how to do this? So far, I have found suggestions to use the CAPI engine (eg. https://groups.google.com/g/mailing.openssl.users/c/_rdJLc7emAY?pli=1), but no examples of how to do that, and also some tickets (eg. https://github.com/openssl/openssl/issues/12859) which say that the CAPI engine does not work with TLS >= 1.2 on openssl 1.1.1, so that doesn't look like a good solution. OpenVPN 2.4+ can use the Windows Certificate Store to encrypt and sign traffic using CNG (Crypto Next Gen, I believe). I'd suggest you download the source code and examine the file cryptoapi.c for details. HTH, JJK
TLS with Client Authentication using private key from Windows store
Hi, I am trying to use openssl to implement a client-side TLS connection with Client Authentication on Windows, using a non-exportable private key stored in the Windows Certificate Store. Currently, our code can use a private key stored in a local file, and if the key in the Windows store was exportable, I could export it and use it in the existing code. But the key is non-exportable, which is a problem. Does anyone know how to do this? So far, I have found suggestions to use the CAPI engine (eg. https://groups.google.com/g/mailing.openssl.users/c/_rdJLc7emAY?pli=1), but no examples of how to do that, and also some tickets (eg. https://github.com/openssl/openssl/issues/12859) which say that the CAPI engine does not work with TLS >= 1.2 on openssl 1.1.1, so that doesn't look like a good solution. Any help would be appreciated! Thank you, Ferenc
Re: Using the library to encrypt a RSA private key compatible with Web Crypto API (PBKDF2)
On Thu, Jul 23, 2020 at 03:04:30PM +, Claude Robitaille wrote: > Now, for sake of completeness, if I wanted to do the opposite, i.e. > decrypt a key, I guess the steps are the same, using > PEM_read_bio_PKCS8 at the end. Except that the salt and IV must be > extracted from the PEM string. What is the function to do that? Reading is much simpler: EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); Just set pass = "sesame" and call: EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio_in, NULL, NULL, pass); It is possible to use the PKCS8 routines explicitly with: PKCS8 *PEM_read_bio_PKCS8(BIO *bp, TYPE **a, pem_password_cb *cb, void *u); as follows: X509_SIG *p8 = PEM_read_bio_PKCS8(bio_in, NULL, NULL, NULL); PKCS8_PRIV_KEY_INFO *p8inf = PKCS8_decrypt(p8, pass, strlen(pass)); EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf); but there's little reason to do that. The PBE algorithm, salt and IV are handled internally. -- Viktor.
Re: Using the library to encrypt a RSA private key compatible with Web Crypto API (PBKDF2)
Super, that works beautifully. Thanks!! Now, for sake of completeness, if I wanted to do the opposite, i.e. decrypt a key, I guess the steps are the same, using PEM_read_bio_PKCS8 at the end. Except that the salt and IV must be extracted from the PEM string. What is the function to do that? From: openssl-users on behalf of Viktor Dukhovni Sent: July 22, 2020 7:17 PM To: openssl-users@openssl.org Subject: Re: Using the library to encrypt a RSA private key compatible with Web Crypto API (PBKDF2) On Wed, Jul 22, 2020 at 08:36:30PM +, Claude Robitaille wrote: > This is NOT about using the command line utility, it is about using > the library in a program and exporting a private key, while encrypting > it. Encrypted public keys are created via the PKCS8 API. > Now, for my application. I am not sure how to do this. I normally use > PEM_write_bio_PKCS8PrivateKey to generate a PEM string. That function > do accept a passphrase and a cipher but it is not possible to set > parameters. The default values, as I could gather by reading on the > Internet are weak so I just do not want to lower the Web Crypto API > end. How to proceed? Is there another function that can be used? The function you're looking for is PEM_write_bio_PKCS8_PRIV_KEY_INFO(). With error checks elided, it boils down to: 1. const EVP_CIPHER *cipher = EVP_get_cipherbyname(SN_aes_256_cbc); 2. X509_ALGOR *pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL, NID_hmacWithSHA512); The function in question needs documentation, it would be fanstastic if someone stepped up to document it, or at least open an issue asking for same: X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, unsigned char *salt, int saltlen, unsigned char *aiv, int prf_nid); When the IV is null a random IV is generated. When the salt is NULL and saltlen == 0 a random salt is used. /* When saltlen is 0 and salt is not NULL you may get a segfault! */ The return value is freed with: void X509_ALGOR_free(X509_ALGOR *); 3. PKCS8_PRIV_KEY_INFO *p8inf = EVP_PKEY2PKCS8(pkey); 4. X509_SIG *p8 = PKCS8_set0_pbe(pass, strlen(pass), p8inf, pbe); Here, you might want to pay attention to the character set in which the password is encoded, if it is not all ASCII, it should be UTF-8 (https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftools.ietf.org%2Fhtml%2Frfc8018&data=02%7C01%7C%7C6ecb294783f64bd662eb08d82e969dbe%7C84df9e7fe9f640afb435%7C1%7C0%7C637310571707466330&sdata=QJ0dIUR%2FOsrgZn2SpnoRLHQRNZ1E7T4sB0O1CJyWIK8%3D&reserved=0) 5. BIO *bio_out = ... 6. ret = PEM_write_bio_PKCS8(out_bio, p8); -- Viktor.