Re: Question about migrating from d2i_ECPrivateKey() to d2i_PrivateKey(EVP_PKEY_EC, ...)
On Tue, Nov 22, 2022 at 11:09:07AM -0600, Nico Williams wrote: > > Not exactly, PKCS#8-based typing is used in d2i_PKCS8_PRIV_KEY_INFO() > > (for unencrypted PKCS#8 blobs, so no password callback). The > > d2i_PrivateKey() function takes an explicit pkey_type instead. > > Hmmm, well, d2i_PrivateKey() takes an explicit pkey_type, yes, but it's > not sufficiently informative for ECDH, being just EVP_PKEY_EC. Or are > there more informative type values I've not discovered yet? When I call > d2i_PrivateKey(EVP_PKEY_EC, ...) it wants a PKCS#8 encoded private key. Actually, it supports *both* the PKCS#8 and the legacy type-specific formats. The algorithm-specific PEM key formats may not be defined for some newer key types and are deprecated, so sure, you're supposed to use PKCS#8 whenever possible. For EC private keys, the underlying legacy DER codecs are: d2i_ECPrivateKey() i2d_ECPrivateKey() with signatures: EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len); int i2d_ECPrivateKey(const EC_KEY *a, unsigned char **out); for d2i_ECPrivateKey(), you get back an EC_KEY() which you can convert to an EVP_PKEY via the deprecated (copy vs. take ownership): EVP_PKEY_set1_EC_KEY(3), or EVP_PKEY_assign_EC_KEY(3) which direct you to EVP_PKEY_fromdata(3) (much scaffolding...). However, d2i_PrivateKey(EVP_PKEY_EC, ...) given non-PKCS#8 input internally tries: static int old_ec_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { EC_KEY *ec; if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL) return 0; EVP_PKEY_assign_EC_KEY(pkey, ec); return 1; } which does the expected thing without much fuss. That said, you mentioned ECDH in passing, so I'm not sure we're taking about the same things... -- Viktor.
Re: How to read encrypted PKCS#8 format key file
On Thu, Nov 24, 2022 at 09:48:42AM +0530, Satyam Mehrotra wrote: > I have encrypted pkcs#8 key file . Is there any openssl command buy which I > can view the algorithm used to encrypt it ( i mean aes or des3 ) Removing blank lines and passing to "asn1parse" you get: $ openssl asn1parse -in /tmp/foo.pem | less 0:d=0 hl=4 l=1302 cons: SEQUENCE 4:d=1 hl=2 l= 72 cons: SEQUENCE 6:d=2 hl=2 l= 9 prim: OBJECT:PBES2 17:d=2 hl=2 l= 59 cons: SEQUENCE 19:d=3 hl=2 l= 35 cons: SEQUENCE 21:d=4 hl=2 l= 9 prim: OBJECT:PBKDF2 32:d=4 hl=2 l= 22 cons: SEQUENCE 34:d=5 hl=2 l= 16 prim: OCTET STRING [HEX DUMP]:54BE686300BD75A2A58678D3AA746803 52:d=5 hl=2 l= 2 prim: INTEGER :0800 56:d=3 hl=2 l= 20 cons: SEQUENCE 58:d=4 hl=2 l= 8 prim: OBJECT:des-ede3-cbc 68:d=4 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:39557361E14C06F5 78:d=1 hl=4 l=1224 prim: OCTET STRING [HEX DUMP]:0DFC7C23573AC5C76C368927B27178E5F877E15359E01CABE280FEAF572535985A8C7981075B995A94633193CF425432CAF9B6AE5BE978443B010CD453CF19C434DB6CD11B65ACC06F6C573EFC7FE3F667EAA4EFEC7088E953CD01AC6ADD38214275852765FF0309FB777E99EBE3A12FADC5E7DCF2A7A68F47DD018C39B1430B34C4A4329EA94E21D23B3D8B34F6F828F1340321685EC6F4E2F878A7B95EE710E8CD570109DDE90EC8D553C5A93E36E5F374E6670828DAA4F096183B77063E6F865F83E353861D864702AA18984A413B345D39464C055B8C7EB2D339AE04FEE4932F629E9736A3FA2D770528C07DCAE9950AD9CDE2EC838DABFE4BF40C745B447CF5D461B5B7EBD3BD1C050F129FC989684589CE6D780C126395C5749536A8E82902332EA9DB7174768780378D644029986FF2463184CD33B8DD1D4692ADF6CE0A9902A3459353102572A0AF981F96C66B6C2D8EF31BDAD438AB9E1D6CF897985713E6F5B5E2178A6F65AE582DEA2778E9041C2BC3C9B33EEDBFB19C439F5754FBACB61521711D7992CE2CCD5DC7A0AA543D3A93401031EFD39ABD435385C287A1F503686707A02E3AA2D5183CF9F2DA6436C7B51B46BFE31999592D35B099DE7FE68914610D09854E3B02A0773EB2367B7FA04205FC4500FED6AD0FF84E8A0EB183AFC84D2ABB1C43E8097C169097F3E2D744E3D31339AD024CD613733CC185F49C44B538ECA4BC63E7FA95E5F9A50E2DBD05DFC09724C6F729B5ACF41B5889C0C74B6979AEBEA3B5C73CA68AF8983DF69BEAC9BB8C1267E048B1AFE1D61757FA5D9543CE7FC4BA22D5A498FD9A1FB2A3430A56214F43D27A41B68C784F875AC29047608FEF4E3CFA69629C14558BABBA26063404D598AE927D34C642517AB9B458D51095EBFCFF67901ADF7151C6BCC336F447B437997E9C1C4DB3EF79D6A1CB7F673D32FED0010B6B6BE532F1E96F0DE04F20618615958628CB444CF952992FB5A3BF440501A768E9C91272B560E3F526306EE8FA61A46A7F1FB04B2B9D3954255AD4FF80C96950D20181657ED45F79C33186362686E969FE474B51E53F97F9FAA9F2FD40DDCE65C8406BE873418ED1EA6872C14420BE4A050F5715901AB5F8F21D256017B2C459F9289E00B8437C80A9DEBF857F87CDD18B29B131707984067D41B7C6B09B19CE942B9625CE69DD2F6F40F175568DBE69AD0DCD6971E87E9342DCAB8E7484C875FC2888D4EC13AB4748115DC9ECCE34B6D3C228C519FBD2BECB921946616A3F37E91F9DA275E0087D3C1AE74EF69E7EA57B94CE6A103122007D89E2C10277C0D56AD2BD18BC93B0D68DD43A4B9DF80368DD87AF55463A044CA2E603617BEA25DD37A15F8EB565FFA46160ABFAE2A47D5B9DE2AC6C8A79501389BEF33605EA95FA78521FB6561632006E45DCC4A6A9E68914CC63B3B27E1C29959A4224BE4DFB3CBEAD00C4DA6B004B5A30148543D4E83FF6AA0782A08DE95E42DEEA3B91EF45B9B14C9D28CD77DE8508CCDE4B10F2C36272C4D3CE348D4C268EE44C275F26556C66EB99BA2565D07F604BA6320FC5186847541162A0BAAA3250ECADC21DDED850B221517379BAA0241E537971325A96434C818A7FA2C3746E5DBC71074365BC6805F94A8ECAB84F6C4A9A9A1D9795667D3D342A37DECB8936ADFEC1232DA06A764DFF8166C040E62E7C0F09DCA4055200CEAC771D1139EA464CD51A947E360A This is a PKCS#8 key using PKCS#5 PBES2 encryption, via PBKDF2 with salt 0x54BE686300BD75A2A58678D3AA746803 and 2048 iterations and an implicit HMAC-SHA-1 PRF, encrypted with 3DES in CBC mode with 0x39557361E14C06F5 as the IV. https://www.rfc-editor.org/rfc/rfc8018#section-6.2.1 PBKDF2-params ::= SEQUENCE { salt CHOICE { specified OCTET STRING, otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}} }, iterationCount INTEGER (1..MAX), keyLength INTEGER (1..MAX) OPTIONAL, prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 } SupportingAlgorithms ALGORITHM-IDENTIFIER ::= { {NULL IDENTIFIED BY id-hmacWithSHA1} | {OCTET STRING (SIZE(8)) IDENTIFIED BY desCBC} | {OCTET STRING (SIZE(8)) IDENTIFIED BY des-EDE3-CBC}| {RC2-CBC-Parameter IDENTIFIED BY rc2CBC} | {RC5-CBC-Parameters IDENTIFIED BY rc5-CBC-PAD},| {OCTET STRING (SIZE(16)) IDENTIFIED BY aes128-CBC-PAD} | {OCTET STRING (SIZE(16)) IDENTIFIED BY aes192-CBC-PAD} | {OCTET STRING (SIZE(16)) IDENTIFIED BY aes256-CBC-PAD}, ... } -- Viktor.
Re: Question about migrating from d2i_ECPrivateKey() to d2i_PrivateKey(EVP_PKEY_EC, ...)
On Tue, Nov 22, 2022 at 11:09:07AM -0600, Nico Williams wrote: > > Not exactly, PKCS#8-based typing is used in d2i_PKCS8_PRIV_KEY_INFO() > > (for unencrypted PKCS#8 blobs, so no password callback). The > > d2i_PrivateKey() function takes an explicit pkey_type instead. > > Hmmm, well, d2i_PrivateKey() takes an explicit pkey_type, yes, but it's > not sufficiently informative for ECDH, being just EVP_PKEY_EC. Or are > there more informative type values I've not discovered yet? When I call > d2i_PrivateKey(EVP_PKEY_EC, ...) it wants a PKCS#8 encoded private key. Do you mean ECDH or ECDSA? These are not exactly the same use case. What are you actually doing? Are you really doing static ECDH key agreement? -- VFiktor.
ASN1 function declarations
On Tue, Nov 22, 2022 at 11:09:07AM -0600, Nico Williams wrote: > Also, the prototype for i2d_PUBKEY() does not appear in any header, > public or private, but i2d_PUBKEY() _is_ documented -- is this a bug? The d2i_* and i2d_* functions are mostly generated by macros that declare all or some of the functions for a given ASN1 type: openssl/x509.h:DECLARE_ASN1_ENCODE_FUNCTIONS_only(EVP_PKEY, PUBKEY) openssl/x509.h:DECLARE_ASN1_FUNCTIONS(X509) This can admittedly be a bit annoying when searching the right header is more convenient that finding the right manpage, but search engines are pretty good these days, and the openssl.org website has a doc index: https://www.openssl.org/docs/manpages.html https://www.openssl.org/docs/man3.0/man3/ ... -- Viktor.
Re: Question about migrating from d2i_ECPrivateKey() to d2i_PrivateKey(EVP_PKEY_EC, ...)
On Sun, Nov 20, 2022 at 02:12:34PM -0600, Nico Williams wrote: > > Generally, I would expect d2i_... to automatically detect the algorithm > > when tagged with a suitable OIDs, and so d2i_AutoPrivateKey() could > > often work, but if you know the expected key type, you can ask for > > that explicitly with d2i_PrivateKey(). > > So, d2i_PrivateKey() wants a PKCS#8 wrapper so it can figure out what > the type of the private key blob is. Not exactly, PKCS#8-based typing is used in d2i_PKCS8_PRIV_KEY_INFO() (for unencrypted PKCS#8 blobs, so no password callback). The d2i_PrivateKey() function takes an explicit pkey_type instead. > On the other hand, d2i_PublicKey() wants the input key to indicate the > type of public key to import. A strange asymmetry, but it works. > Staring at Postfix and OpenSSL code helped. For X.509 SPKI public keys (the ones you generally want to use) the right interface is d2i_PUBKEY, not d2i_PublicKey(). -- Viktor.
Re: Question about migrating from d2i_ECPrivateKey() to d2i_PrivateKey(EVP_PKEY_EC, ...)
On Fri, Nov 18, 2022 at 11:33:08PM -0600, Nico Williams wrote: > On Fri, Nov 18, 2022 at 04:53:44PM -0600, Nico Williams wrote: > > I can't use d2i_PrivateKey() because that requires an existing > > EVP_PKEY * that has the group already set. > > Although, that's just what's documented. From code inspection, if the > parameters are found in the encoded private key, then the group will be > set internally and no error will be returned. Often, if you want a clear example of OpenSSL API usage, one place to look is the Postfix "tls" library. In this case: https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L245-L266 https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L363-L370 Postfix does not do much with low-level crypto, but it exercises a non-trivial chunk of the certificate and TLS API surface, ECDH/DH setup and digests. Generally, I would expect d2i_... to automatically detect the algorithm when tagged with a suitable OIDs, and so d2i_AutoPrivateKey() could often work, but if you know the expected key type, you can ask for that explicitly with d2i_PrivateKey(). You don't need to pass an existing key. Just pass NULL for (EVP_PKEY **) pointer, and let OpenSSL return a freshly allocated key: EVP_PKEY *key; key = d2i_PrivateKey(type, NULL, ...); key = d2i_AutoPrivateKey(NULL, ...); I strive to also check that the buffer pointer advanced by the expected length (no "left-over" data): https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L293-L306 -- Viktor.
Re: Regarding TLS call failure on Openssl3.0 with cipher : ECDH-ECDSA-AES256-SHA384
On Fri, Nov 18, 2022 at 05:12:09AM +, Raman, Ina wrote: > I was trying to test TLS call with cipher suite : > tls_ecdh_ecdsa_with_aes_256_cbc_sha384 but it fails. You probably actually wanted "ecdhe" not "ecdh", but see below. > It fails on SSL_set_cipher_list API. This API, and the cipher you had in mind apply only to TLS 1.2, with TLS 1.3 there is a separate API for setting the data encryption ciphers, which are configured separately from signature schemes, and key exchange "groups", but see below. > The list contains the mentioned cipher but still it is failing to set > that. Actually the list does not contain that cipher: - The available TLS 1.2 ciphers are ECDHE not ECDH. $ openssl ciphers -stdname -s -tls1_2 | awk '{print $1}' | grep ECDH TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_CCM TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_128_CCM TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - The standard names are "output only" when configuring ciphers you need to use the OpenSSL names. $ openssl ciphers -stdname -s -tls1_2 -v ECDHE-ECDSA-AES256-GCM-SHA384 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD $ openssl ciphers -stdname -s -tls1_2 -v TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 Error in cipher list C0F16339DF7F:error:0AB9:SSL routines:SSL_CTX_set_cipher_list:no cipher match:ssl/ssl_lib.c:2746: - Cipher names are case-sensitive. $ openssl ciphers -stdname -s -tls1_2 -v $(echo ECDHE-ECDSA-AES256-GCM-SHA384 | tr A-Z a-z) Error in cipher list C0F1755DCB7F:error:0AB9:SSL routines:SSL_CTX_set_cipher_list:no cipher match:ssl/ssl_lib.c:2746: - TLS 1.3 uses none of the above: $ openssl ciphers -s -v -tls1_3 TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD TLS_AES_128_CCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESCCM(128) Mac=AEAD > I wanted to know if this cipher is supported with openssl 3.0 or not . Multiple mistakes: * Wrong API for TLS 1.3 * Desired cipher not applicable to TLS 1.3 anyway * Typo "ecdh" instead of "ecdhe" * Cipher name was lower case * Cipher name was the RFC name, not the OpenSSL name. Any one mistake it sufficient, but 5 is impressive. :-) -- Viktor.
Re: Worried about the vulnerabilities recently found in OpenSSL versions 3.0.0 - 3.0.6.
On Wed, Nov 02, 2022 at 11:17:31PM +, Steven_M.irc via openssl-users wrote: > I'm really worried about the vulnerabilities recently found in OpenSSL > versions 3.0.0 - 3.0.6. Just upgrade any affected systems and you'll be fine. > If I understand things correctly (and please do correct me if I'm > wrong), it doesn't matter which version of OpenSSL clients are > running, only which version of OpenSSL *servers* are running. Your information source is either wrong or misleading. The only software version that matters is the one your system is running, whether client or server. -- Viktor.
Re: issues with OpenSSL 1.1.1n
On Tue, Nov 01, 2022 at 06:08:10PM -0500, Ray Crumrine wrote: > Oh my gosh! Thank you. I am a newbie when it comes to certificates. I > am only using tls for outbound calls. I thought I shouldn't need a > certificate when doing outbound only [a client] but was getting some > weird error. After I read your email I simply commented out both > "certificate" lines in my configuration and it works!!! You don't need (and generally should not configure) client certificates for connections to random servers that are not specifically expected to authenticate your client certificates. > One last question. I don't need certbot at all then, right? If you're not running any TLS-enabled servers, and no server expects hostname-based TLS client certificates from your client, then indeed you do not need certbot. It vends TLS server/client certificates for domain names based on trust-on-first-use verified DNS domain control. -- Viktor.
Re: issue with 1.1.1n
On Tue, Nov 01, 2022 at 05:55:08AM -0500, Ray Crumrine wrote: > SSL SSL_ERROR_SSL (Handshake): Level: 0 err: <336151573> routines-ssl3_read_bytes-sslv3 alert certificate expired> Is this logged by the TLS client or server? In other words are you running a client application making outgoing connections or a server application receiving incoming connections? > but not all of the time. Only when I try to access > us-east-va.sip.flowroute using tlsv1.2. This sounds like "client". TLS alerts are sent by the other end of the connection, so if you're getting "certificate expired" alerts from a server, that means that your client is *sending* an expired certificate to the server (which must have solicited, possibly optional, client certificates). The server in question does send certificate requests: Transport Layer Security TLSv1.2 Record Layer: Handshake Protocol: Certificate Request (fragment) Content Type: Handshake (22) Version: TLS 1.2 (0x0303) Length: 16384 Handshake Protocol: Certificate Request (fragment) ... > I have tried two other sites using the same configuration and they work > fine. Is there a simple configuration change or do I need Openssl v3.0? The other sites presumably don't solicit client certificates. The simplest choice is to not configure a client certificate unless you're sure you're going to need one. > Checking with > https://decoder.link/sslchecker/us-east-va.sip.flowroute.com/5061 > everything checks fine??? The probe does not send expired client certs. -- Viktor.
Re: OpenSSL 1.1.1 Windows dependencies
On Wed, Oct 26, 2022 at 11:50:16AM -0400, Viktor Dukhovni wrote: > On Wed, Oct 26, 2022 at 11:15:25AM +0100, Matt Caswell wrote: > > > > I'm not promising anything. But if you send me the captures I can take a > > > look at them. > > > > I've taken a look at the captures for the working and non-working scenarios. > > > > Do I understand correctly that your application is acting as the server > > in this setup? > > > > I have compared the working and non-working captures. In both cases the > > ClientHello is successfully received, and the server responds with a > > ServerHello, Certificate, ServerKeyExchange and ServerHelloDone message. > > Aside from normal variations between one session and another, AFAICT, > > the ClientHello and the server's response messages all look identical > > other than the server obviously has a different Certificate. The > > Certificates themselves also look identical to each other other than the > > subject/subjectaltname being for a different server. The intermediate > > certs are the same in both cases. > > > > Following the server's ServerHelloDone the client continues with a > > ClientKeyExchange message in the working case. In the non-working case > > the the client immediately closes the TCP connection without sending any > > kind of alert. > > See longish thread at: > > https://marc.info/?l=postfix-users=166584042429636=2 > > which describes a remarkably similar set of symptoms observed after a > Microsoft patch update. Today the OP posted that a more follow-on patch > appears to have resolved the problem. TL;DR: progress on identifying the issue begins with: https://marc.info/?l=postfix-users=166585652703462=2 -- Viktor.
Re: OpenSSL 1.1.1 Windows dependencies
On Wed, Oct 26, 2022 at 11:15:25AM +0100, Matt Caswell wrote: > > I'm not promising anything. But if you send me the captures I can take a > > look at them. > > I've taken a look at the captures for the working and non-working scenarios. > > Do I understand correctly that your application is acting as the server > in this setup? > > I have compared the working and non-working captures. In both cases the > ClientHello is successfully received, and the server responds with a > ServerHello, Certificate, ServerKeyExchange and ServerHelloDone message. > Aside from normal variations between one session and another, AFAICT, > the ClientHello and the server's response messages all look identical > other than the server obviously has a different Certificate. The > Certificates themselves also look identical to each other other than the > subject/subjectaltname being for a different server. The intermediate > certs are the same in both cases. > > Following the server's ServerHelloDone the client continues with a > ClientKeyExchange message in the working case. In the non-working case > the the client immediately closes the TCP connection without sending any > kind of alert. See longish thread at: https://marc.info/?l=postfix-users=166584042429636=2 which describes a remarkably similar set of symptoms observed after a Microsoft patch update. Today the OP posted that a more follow-on patch appears to have resolved the problem. > This really looks like a problem on the client side to me. Yes, the client just hangs up. A known. Disabling session tickets on server appears to help in some cases (for no obvious reason). Applying the follow-on update is a better solution if applicable. -- Viktor.
Re: Question about thread safety and SSL_CTX* and its SSL*
On Tue, Sep 27, 2022 at 06:35:47PM +0200, Thomas Bailleux wrote: > However, I am still facing issues when I use `SSL_CTX` and `SSL` objects. > > I use `SSL_CTX` and `SSL` inside a threaded application. Threads are managed > using pthread primitives. > > Basically, I create a `SSL_CTX`, and I fill it depending on the TLS method. > At this point, the `SSL_CTX` is final. I never change it again. > > Then, I create n `SSL`s from the `SSL_CTX`, and I spawn n pthreads. > Each pthread takes the ownership of a single `SSL`. Finally, each > pthread is going to use its `SSL` object for establishing some TLS > connections. `SSL` objects never get destroyed, instead I use > `SSL_clear` for kind of recycling them. Perhaps you're freeing some objects that are owned by the library, or continuting to use objects that the library owned and freed. > My question is: Is my app thread safe ? I wonder, because I am facing > random null deref. If I create a `SSL_CTX` for each thread, > everything is fine. What you're doing should work, if implemented correctly, but my advice is to not use SSL_clear(), rather create a fresh (SSL *) handle for each connection. These are cheap enough to not warrant recycling. -- Viktor.
Re: Query minimum RSA key size?
On Mon, Sep 26, 2022 at 10:46:40AM -0400, Felipe Gasper wrote: > > The security levels are documented. You can set the security level > > in the cipher string: > > > >DEFAULT:@SECLEVEL=1 > > > > or via the API. > > Ahh, OK. Indeed, when I set that as the cipher string the error goes away. > Thank you! You can, if you wish, change the default security level in openssl.cnf. IIRC the default from the upstream OpenSSL software is 1. If your system default is 2 or higher, that was done by your OS package maintainers. > I see that the API exposes SSL_CTX_get_security_level(); is that the > best way to determine minimum RSA key size, or would there be anything > more explicit? The documentation for that function reads in part: Level 0 Everything is permitted. This retains compatibility with previous versions of OpenSSL. Level 1 The security level corresponds to a minimum of 80 bits of security. Any parameters offering below 80 bits of security are excluded. As a result RSA, DSA and DH keys shorter than 1024 bits and ECC keys shorter than 160 bits are prohibited. Any cipher suite using MD5 for the MAC is also prohibited. Any cipher suites using CCM with a 64 bit authentication tag are prohibited. Note that signatures using SHA1 and MD5 are also forbidden at this level as they have less than 80 security bits. Additionally, SSLv3, TLS 1.0, TLS 1.1 and DTLS 1.0 are all disabled at this level. Level 2 Security level set to 112 bits of security. As a result RSA, DSA and DH keys shorter than 2048 bits and ECC keys shorter than 224 bits are prohibited. In addition to the level 1 exclusions any cipher suite using RC4 is also prohibited. Compression is disabled. Level 3 Security level set to 128 bits of security. As a result RSA, DSA and DH keys shorter than 3072 bits and ECC keys shorter than 256 bits are prohibited. In addition to the level 2 exclusions cipher suites not offering forward secrecy are prohibited. Session tickets are disabled. Level 4 Security level set to 192 bits of security. As a result RSA, DSA and DH keys shorter than 7680 bits and ECC keys shorter than 384 bits are prohibited. Cipher suites using SHA1 for the MAC are prohibited. Level 5 Security level set to 256 bits of security. As a result RSA, DSA and DH keys shorter than 15360 bits and ECC keys shorter than 512 bits are prohibited. Levels 4 and 5 are tantamount to making RSA and DSA unavailable. Even level 3 is too distruptive for interoperable use on the public Internet. As you observed, Level 2 disables 1024-bit RSA. The symmetric equivalent bit strength of a particular public key can be queried via: EVP_PKEY_security_bits(3): EVP_PKEY_security_bits() returns the number of security bits of the given pkey, bits of security is defined in NIST SP800-57. -- Viktor.
Re: Query minimum RSA key size?
On Mon, Sep 26, 2022 at 09:52:29AM -0400, Felipe Gasper wrote: > OpenSSL 1.1.0k introduced behaviour that rejects 1,024-bit RSA key sizes. No such change was made. Perhaps your OS distribution has bumped the default (TLS) security level from 1 (80-bit or more) to 2 (~112 bit or more). You can look in the system-wide openssl.cnf file. > Is the new minimum key size queryable? It appears to be 2,048, but in > the event that that changes again I’d ideally love just to grab that > value from OpenSSL itself rather than hard-coding it. The security levels are documented. You can set the security level in the cipher string: DEFAULT:@SECLEVEL=1 or via the API. -- VIktor.
Re: PEM to EVP_PKEY
On Sun, Sep 25, 2022 at 04:12:57PM -0700, Kory Hamzeh wrote: > So I have a PEM formatted file that contains an EC certificate and a > private key. I need to load that PEM file and converted to an > EVP_PKEY. The goal of this exercise is so that I can do an ECDH > pairwise consistency test (SP 800-56Ar3 Section 5.6.2.1.4) on the key > pair by calling EVP_PKEY_pairwise_check(). I need some help in getting > from the PEM file to an EVP_PKEY. For an "atomic" interface, that reads both from the same file, even if the file is replaced (atomically, via rename(2)) while the key and cert are being read: 1. https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L344-L378 2. https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L245-L266 For a simpler interface that is subject to races vs. atomic updates: https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L245-L266 -- Viktor.
Re: Problem with Asymetric, two-key encryption and Certificate Requests.
On Mon, Sep 19, 2022 at 01:32:40AM +, A Z wrote: > A#) openssl req -x509 -nodes -newkey rsa:4096 -keyout private.key -out > public.key > > B#) openssl smime -encrypt -binary -aes-256-cbc -in message.txt -out > encrypted.dat -outform DER public.key > > C#) openssl smime -decrypt -in encrypted.dat -binary -inform DEM -inkey > private.key -out decrypted.txt > > How can I complete step A#), so that step B#) will work, without > involving a Certificate Request, which requires a non-blank two digit > nation code, > > 'You can set an empty issuer/subject DN, or use "-keyid" to avoid > copying these into the CMS message.' > > Can someone please update my included A#), B#) or C#) instructions, > included above here, to acheive this suggestion, so that no > certificate information is put into 'encrypted.dat', including the > nation, so that 'encrypted.dat' includes no plain text whatsoever, and > so that A#) + B#) + C#) all work as desired, for small, medium and > large files, of 'message.txt'? I am struggling to correct what I have > done so far, so that there are no errors, and so that all the steps > work: (generation of a private and public key, encryption of the file, > and decrypt of the file). ? 1. Generate the self-signed certificate using a configuration that sets a subject key id. 2. Also set an empty subject name via "-subj /". The example also sets a 100 year expiration time. $ openssl req \ -nodes -newkey rsa:4096 -keyout pkey.pem \ -x509 -out cert.pem \ -days 36500 -subj / \ -addext "subjectKeyIdentifier=hash" 3. Use "openssl cms" insteadm of "openssl smime", and set the "-keyid" option when encrypting. $ openssl cms -keyid -encrypt -binary -aes-256-cbc \ -in /some/file -out /some/file.cms -outform DER \ -recip cert.pem [ There appears to be a bug in the implementation of the "-keyid" option in OpenSSL 1.1.1. It works with OpenSSL 3.0.5. ] You're not *signing* the content. It is trivially spoofed, because unless the public certificate is also kept secret, anyone can encrypt a substitute file, and decryption will later succeed. Instead of worrying about insignificant plaintext metadata, you should be worrying about data integrity, and related actually relevant issues, some noted below. 4. Again use "openssl cms" to decrypt. $ openssl cms -decrypt -in /some/file.cms -binary -inform DER \ -inkey pkey.pem -out /some/file.dat [ But see above, you have zero guarantee that the file has not been tampered with by some with access to the non-secret public key. ] It is rather puzzling why it would be a problem to set some correct or bogus 2-letter country code. It in no way compromises the security of the data. That said, you can avoid this if it really bugs you. As to the goal of encrypting "large files", note that neither CMS, nor SMIME are particularly well suited in that regard. Decryption of CMS messages brings the entire encrypted object into memory, this does not scale well for "large files". For large file encryption you'd ideally want to break the file into chunks (say 4MB each), separately encrypt and MAC (HMAC is harder to misuse than AEAD) each block's sequence number and data under a symmetric key. Then separately encrypt (and sign!) a data structure with any relevant file metadata and symmetric key with CMS. (The metadata should typically include the file name, modification time, ... so that malicious substitution of some other file is later easier to detect). A final < 4MB length block would signal the end of the file. Decryption needs to verify the signature, decrypt the metadata, recover the symmetric key, and then decrypt all or some of the blocks, verifying the sequence numbers, and (if recovering the whole file) that the last block (possibly empty) is shorter than the chunk size. Decryption can then proceed one block at a time, with each block verified independently without having to buffer the entire file. A proper encrypted backup design requires more care than just naive use of CMS (or its precursor S/MIME). You're fixating on entirely the wrong set of issues. -- Viktor.
Re: Problem with Asymetric, two-key encryption and Certificate Requests.
On Thu, Sep 08, 2022 at 02:08:40AM +, A Z wrote: > I have wanted to get into public/private two key encryption, of > computer files of any type and any size and type. I am working on > Windows 10 64 bit.I found the ensuing approach by my own > experimenting, but it has a key disadvantage. What threat model requires you to obscure all traces of cleartext metadata in the encrypted message? In most common formats, in order to facilitate algorithm agility, at least the encryption algorithm identifier (often an ASN.1 OID) is included in the clear. > In order for the encryption step to work by means of the public key, > I have found the following approach with relies on the generation of a > Certificate Request. The problem is however, that by doing things like this, > > A#) openssl req -x509 -nodes -newkey rsa:16384 -keyout private.key -out > public.key This actually generates a self-signed X.509 certificate. You can the -subj / -days 3650 options to set empty subject and issuer DNs and (given self-signed cert) a 10-year or longer validity. Use of RSA 16384 is ludicrous. Anything longer than 4096 bits is just posturing and even that is overkill, once/if 2048-bit RSA is broken, the rest will surely follow in quick succession... > B#) openssl smime -encrypt -binary -aes-256-cbc -in message.txt -out > encrypted.dat -outform DER public.key In S/MIME (or its more modern incarnation as CMS) each recipient's wrapped key carries a suitable recipient identifier: https://www.rfc-editor.org/rfc/rfc5652#section-6.2 KeyTransRecipientInfo ::= SEQUENCE { version CMSVersion, -- always set to 0 or 2 rid RecipientIdentifier, keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, encryptedKey EncryptedKey } RecipientIdentifier ::= CHOICE { issuerAndSerialNumber IssuerAndSerialNumber, subjectKeyIdentifier [0] SubjectKeyIdentifier } If you want to use a key identifier instead of (issuerDN + serial), you can use the "-keyid" option of the cms(1) command, having first made sure that the certificate you generate carries a subject key identifier. > I can get plain text injected into the encrypted text, which I want to > totally avoid every part of. Your aversion to "plaintext" here looks poorly motivated. It is just CMS (S/MIME) recipient metadata. CMS is not deniable encryption, the outer layers of encapsulation are not encryption. > How can I complete step A#), so that step B#) will work, without involving a > Certificate Request, which requires > a non-blank two digit nation code, You can set an empty issuer/subject DN, or use "-keyid" to avoid copying these into the CMS message. -- Viktor.
Re: AW: [EXTERNAL] Stricter pathlen checks in OpenSSL 1.1.1 compared to 1.0.2?.
On Fri, Sep 16, 2022 at 02:11:38PM +, Andrew Lynch via openssl-users wrote: > http://sm-pkitest.atos.net/cert/Atos-Smart-Grid-Test.CA.2.crt > > I’ve also asked my colleagues why the download is http instead of https… You should look to multiple independent sources to validate the authenticity of a trust anchor public key. Trusting "https" to prove the validity of a WebPKI trust anchor is a bit too circular. Also "https" is redundant for CRL and intermediate CA distribution, since these are signed by the issuing CA. That said, the same ".crt" file is availabe via "https": https://sm-pkitest.atos.net/cert/Atos-Smart-Grid-Test.CA.2.crt Trust anchor certificates are often delivered as an operating system "package", and ideally the package maintainers apply proper due diligence. -- Viktor.
Re: AW: [EXTERNAL] Stricter pathlen checks in OpenSSL 1.1.1 compared to 1.0.2?.
On Fri, Sep 16, 2022 at 08:32:27AM +, Andrew Lynch via openssl-users wrote: > So is this a possible bug or a feature of OpenSSL 1.1.1? (using > 1.1.1n right now) OpenSSL 1.1.1 is doing the right thing. > If I set up the content of CAfile or CApath so that E <- D <- C <- A > is the only path that can be taken then the validation fails with There are two intermediate CA certificates (C and D) in this path. This path should be rejected when the path length constraint of A is set to 1. > If I create the first root certificate (A) with pathlen:2 instead of > pathlen:1 then validation succeeds As expected. > So it appears to me that OpenSSL 1.1.1n is definitely taking the > pathlen constraint of certificate A into account. As expected. While A's self-signed certificate is not counted in the path length, its path length constraint is honoured and applied to the rest of the non-EE (and not self-issued) CA certificates in the chain. On Fri, Sep 16, 2022 at 12:23:12PM +, Corey Bonnell via openssl-users wrote: > Can you provide the actual subject DNs for each certificate? RFC 5280 > specifies that self-issued certificates (i.e., issuer DN == subject > DN) are not considered in the pathLen calculation, so knowing whether > these certificates are self-issued or not may be helpful in better > diagnosing the issue. There's no need. Everything is working as expected. -- Viktor.
Re: Stricter pathlen checks in OpenSSL 1.1.1 compared to 1.0.2?
On Thu, Sep 15, 2022 at 05:34:07PM +, Andrew Lynch via openssl-users wrote: > Why is OpenSSL 1.0.2 verifying successfully? Does it not check the > path length constraint or is it actually picking the depth 2 chain > instead of the depth 3? There are two important differences between 1.0.2 and 1.1.1: - In 1.1.1 the trust store is always checked before any untrusted certificates provided by the peer. In 1.0.2 one would have to explicitly set the "trusted first" flag in the store context to get the same behaviour. This can result in different chains being built from the same data. - In 1.1.1 the same checks are applied to both certificates from the peer and the trust store. In 1.0.2, IIRC some checks may have been (incorrectly I believe) applied only to certificates from the peer. I don't recall whether this could affect how path length limits are enforced, or whether 1.0.2 got updated at some point to treat both sources equivalently. Finally, an RFC5280 trust anchor is a public key. Any associated self-signed CA certificate is still CA certificate. Implementations can honour any path length constraint stored in such a certificate. -- VIktor.
Re: Strange problem: openssl verify not working on Proxmox VM, works on a bare metal system
On Sun, Sep 04, 2022 at 08:55:26AM +0100, Roger James via openssl-users wrote: > As I mentioned in an earlier post you need version 1.1 or later of openssl > to successfully validate post September 30, 2021 Lets Encrypt certificates. > The version on your Centos system is 1.0. This is not quite true when using verify(1), because one has complete control over the chain presented for verification via a combination of the: * -trusted anchors.pem, and * -untrusted chain.pem options. The change to "trusted first always" behaviour in OpenSSL 1.1 is relevant to TLS clients validating some Let's Encrypt certificate chains, where the untrusted chain comes from the server, and the DST cross certificate may not find an unexpired trust anchor in the trust store. All that being true, it is not the situation faced by the OP. FWIW, the EE certificate in question can also be verified with OpenSSL 1.0.2, given the right set of untrusted intermediates and trust anchor. -- Viktor.
Re: Strange problem: openssl verify not working on Proxmox VM, works on a bare metal system
On Sat, Sep 03, 2022 at 05:47:25PM -0600, Shawn Heisey via openssl-users wrote: > > Post the output of: > > > > $ openssl crl2pkcs7 -nocrl -certfile > > /etc/ssl/certs/local/DOMAIN.wildcards.pem | > > openssl pkcs7 -print_certs -noout | > > perl -ne 'BEGIN{$/="\n\n\n"} s/\n+/\n/g; print $_, "\n"' > > subject=CN = DOMAIN > issuer=C = US, O = Let's Encrypt, CN = R3 > > subject=C = US, O = Let's Encrypt, CN = R3 > issuer=C = US, O = Internet Security Research Group, CN = ISRG Root X1 Your cert file holds the EE certificate and its R3 intermediate issuer. It does not include a trusted root, therefore when used as the sole trust store, it is not sufficient to verify your EE certificate. If your system's default CApath (also consulted) happens to contain the "ISRG Root X1" issuer CA of "R3", then the certificate validates, otherwise it does not. If that ISRG X1 is only in the default CA file, verification fails, because you've specified your chain as the CAfile instead. > The combined cert file that I have built does NOT contain the root > cert. I only need to send the server cert and the issuing cert. The > browser will have the root cert, so there is no need to send it. This is typically true (unless you've published DANE TLSA records for the root CA), but to match the browser's behaviour, your trust store needs to include the ISRG X1 root, and it does not when you override the CAfile, and CApath fails to bridge the gap. > If I use a file that DOES contain the root cert (one of the files > downloaded by certbot) then I can get it to pass with -untrusted, but > not -CAfile: > > [root@certs ~]# openssl verify -untrusted > /etc/letsencrypt/live/DOMAIN/chain.pem /etc/letsencrypt/live/DOMAIN/cert.pem > /etc/letsencrypt/live/DOMAIN/cert.pem: OK The chain file probably contains the cross-certificate for X1 signed by DST (Digital Signature Trust), and the latter root is in your default system-wide CAfile or CApath. > [root@certs ~]# openssl verify -CAfile /etc/letsencrypt/live/DOMAIN/chain.pem > /etc/letsencrypt/live/DOMAIN/cert.pem > C = US, O = Internet Security Research Group, CN = ISRG Root X1 > error 2 at 2 depth lookup: unable to get issuer certificate > error /etc/letsencrypt/live/DOMAIN/cert.pem: verification failed This invocation does not add the cross certificate. > I suspect this is because the contents of /etc/ssl/certs is so > different. Some already list the ISRG X1 root in the system CAfile or CApath, others do not. OpenSSL does not ship any trusted certificates. Your issue has nothing to do with OpenSSL as such. It is all about the content of the vendor provided trust store and the command-line options you're choosing. -- Viktor.
Re: Strange problem: openssl verify not working on Proxmox VM, works on a bare metal system
On Fri, Sep 02, 2022 at 09:42:13PM -0600, Shawn Heisey via openssl-users wrote: > On an AlmaLinux 8.6 VM hosted in Proxmox: > > [root@certs ~]# openssl verify -CAfile > /etc/ssl/certs/local/DOMAIN.wildcards.pem > /etc/ssl/certs/local/DOMAIN.wildcards.pem > C = US, O = Let's Encrypt, CN = R3 > error 2 at 1 depth lookup: unable to get issuer certificate > error /etc/ssl/certs/local/DOMAIN.wildcards.pem: verification failed Post the output of: $ openssl crl2pkcs7 -nocrl -certfile /etc/ssl/certs/local/DOMAIN.wildcards.pem | openssl pkcs7 -print_certs -noout | perl -ne 'BEGIN{$/="\n\n\n"} s/\n+/\n/g; print $_, "\n"' > If I copy the PEM file to a bare metal system running Ubuntu Server > 20.04, it verifies: Note that OpenSSL verify also looks in the default CApath, and this may vary from system to system. The results may depend on what's installed there. The verify(1) command will attempt to construct a chain to a trusted root using the specified or default CAfile and CApath. You should really be using the "-untrusted" option not the "-CAfile" option: # cert=/etc/ssl/certs/local/DOMAIN.wildcards.pem # openssl verify -untrusted "$cert" "$cert" This adds the untrusted intermediate certs from the cert file to the dataset, without shadowing the default CAfile. -- Viktor.
Re: Session ID is coming as NULL in openSSL 3.0.2 and TLS 1.2 version
On Fri, Sep 02, 2022 at 07:23:41AM +, Sethuraman Venugopal wrote: > The SSL session is getting created successfully, but the session ID is > coming as NULL, due to which the handshake is failing between the > client and server. Successful handshakes need not issue a non-empty session id. The server may not support resumption, or may support only ticket-based resumption and have no session cache. Absence of a session id is NOT a failure, and your code must not require one. https://datatracker.ietf.org/doc/html/rfc5077#section-3.4 > Please suggest me a solution for this issue. Don't require a session id. -- Viktor.
Re: enforcing mutual auth from the client
On Fri, Sep 02, 2022 at 12:22:35AM +, Wall, Stephen wrote: > > A compromised server could easily still request the client certificate, no? > > > But as noted, even a compromised server can ask for client credentials and > > then > > Yes, that's true. If the intruder knew to do so. Also, a thief can > break your window and get into your car, so you might as well leave > them rolled down all the time. > > The question wasn't "Should I care that..." or "Is it a good idea > to...". It was "Can OpenSSL 3 do this". At the conclusion of the handshake you can enquire whether the server sent a CertificateRequest by asking for the list of peer_CA_DNs, via SSL_get0_peer_CA_list(3). If I am not mistaken, the documentation fails to make clear that NULL is returned when the server did not solicit a client certificate, and a non-null (possibly empty) stack of X509_NAME is returned otherwise. Of course this test should only be applied for a full handshake, reused sessions piggyback on the certificates exchanged in the original full handshake. -- Viktor.
Re: enforcing mutual auth from the client
On Thu, Sep 01, 2022 at 09:36:36PM +, Wall, Stephen wrote: > Does OpenSSL 3.0 provide a way for client side software to verify that > the server actually sent a request for the client’s certificate? It is not clear what threat model warrants taking special action when the client certificate is not requested. It could equally be requested and then largely ignored. Note that if resumption takes place the handshake might even happen without presenting the server certificate to the client. -- Viktor.
Re: parsing invalid DER
On Thu, Sep 01, 2022 at 08:21:21AM -0400, Dave Coombs via openssl-users wrote: > These are the 2 invalid encodings I have seen: > > First, a bit-string used for flags, encoded as (hex) 030108. That is, > the number of unused bits is set to 8, and no other content, presumably > indicating no flags are set. DER would have this be 030100 instead. > My d2i is resulting in ASN1_R_INVALID_BIT_STRING_BITS_LEFT in > c2i_ASN1_BIT_STRING(). This is likely not even valid BER, so you'll need a custom decoder to deal with this. > Second, a positive integer with leading 00 padding which is not > necessary, encoded as 80020042. (It has an implicit [0] tag.) DER > would have this be 800142. My d2i is resulting in > ASN1_R_ILLEGAL_PADDING in c2i_ibuf(). This is at least BER, so a BER decoder should be able to handle it. But the "d2i*" routines expect DER, so the above breakage is not d2i-compatible. -- Viktor.
Re: RSA signed ECDSA certificate still uses ECDSA for authentication
On Fri, Aug 26, 2022 at 01:28:21PM -0700, radiatejava wrote: > >> and then the same ECDSA key verified by the CA to sign a hash over the > >> transcript of the handshake itself > > Which part of the TLS handshake you are talking about? Are you talking > about the three messages from the client to server messages that are - > ClientKeyExchange, ChangeCipherSpec, ClientFinished? In my > understanding, ClientKeyExchange, ChangeCipherSpec are not encrypted > and the last one ClientFinished is encrypted but using the keys > derived from ECDHE key exchange algorithm. Is that not right? Other than with TLS 1.0--1.2 anon-DHE and anon-ECDHE ciphersuites, the server key exchange message parameters are signed with the server's public key. If a client certificate is solicited, the client's ClientVerify message is signed with the client's public key. I am not aware of any anon-DHE or anon-ECDHE ciphers for TLS 1.3. I'd advocate for these to be added (for unauthenticated opportunistic TLS), if I did not suspect that there would be little support for them at present. -- Viktor.
Re: OpenSSL errno=104
On Fri, Aug 26, 2022 at 03:59:02AM +, Danilo Singh wrote: > The URL we are trying to connect to is notacarioca.rio.gov.br. When > trying to run an openssl s_client -connect, we get error 104, with the > following return: > write:errno=104 That is a write system call errno value, which translates to: $ perl -le '$! = 104; print "$!"' Connection reset by peer The server is resetting the TCP connection just after receiving the TLS CLIENT HELLO message. Or more likely some oddball firewall in front of the server is doing that. The server refuses to negotiate any ciphers other RSA key exchange (which by the way precludes use of TLS 1.3), and is rather sensitive to the order in which the 'kRSA' ciphers appear in the cipher list. Removing all 'SHA1' ciphers seems to help, but also removing non RSA key-exchange ciphers (while leaving SHA1 enabled) helps. ... -cipher 'DEFAULT:!SHA1' ... ... -cipher 'kRSA:!COMPLEMENTOFDEFAULT' ... So rather unclear what exactly makes the server unhappy, but it does when it works, it seems to choose: 0x00,0x9D - TLS_RSA_WITH_AES_256_GCM_SHA384 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(256) Mac=AEAD otherwise known as 'AES256-GCM-SHA384', which also works if you set it to be the only client cipher. > Currently the OpenSSL configuration on our server looks like this. We > tried several ways, but none worked. As we have little experience with > OpenSSL we don't know what is wrong. > > CipherString = DEFAULT@SECLEVEL=0 The preferred syntax for this is "DEFAULT:@SECLEVEL=0". > Ciphersuites = > TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:TLS_RSA_WITH_AES_128_CBC_SHA256:TLS_RSA_WITH_AES_256_CBC_SHA256:TLS_RSA_WITH_AES_128_GCM_SHA256:TLS_RSA_WITH_AES_256_GCM_SHA384 Perhaps leave these defaulted. > MinProtocol = TLSv1.0 > MaxProtocol = TLSv1.3 > SignatureAlgorithms = > ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:rsa_pss_pss_sha256:rsa_pss_rsae_sha256:rsa_pss_pss_sha384:rsa_pss_rsae_sha384:rsa_pss_pss_sha512:rsa_pss_rsae_sha512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224:ECDSA+SHA1:RSA+SHA1 Perhaps leave these defaulted. -- Viktor.
Re: What is 'trusted certificate'
On Sat, Jul 16, 2022 at 08:45:22AM +0200, David von Oheimb wrote: > To me the below warnings looks strange because usually at depth 0 and 1 > of a cert chain (i.e., at the positions of the end entity cert and any > subsequent intermediate cert) it is normal to have untrusted certs. > Usually only at the end of the chain you have a trusted cert that > represents the trust anchor for the chain. The certificate in question appears to be issued by a private CA, so the immediate issuer may well be the trust-anchor. That said, yes, there is not enough information in the OP's message to determine even whether there is a problem, or what it might be. > > I have freeradius server configured to use EAP-TLS (certificate > > baset authn) Since some time I have warning in logs: > > > > --8<---cut here---start->8--- > > Fri Jul 15 22:29:04 2022 : Warning: (TLS) untrusted certificate with > > depth [1] subject name > > /C=PL/ST=Mazowieckie/L=Warszawa/O=beta/OU=wifi/CN=beta-wifi-ca > > Fri Jul 15 22:29:04 2022 : Warning: (TLS) untrusted certificate with > > depth [0] subject name > > /C=PL/ST=Mazowieckie/O=beta/OU=wifi/CN=salamandra > > --8<---cut here---end--->8--- > > > > I took a look into code and it seems to be related to > > "X509_STORE_CTX_get0_untrusted(ctx)" function. That's almost certainlky a red herring. It returns the list of non helper certificates that are used to build a chain to the root of trust. These are typically the certificates provided by the peer. Trusted certificates come from the local trust store (CAfile, CApath, ...). > > I tried to search, but without success. Can anyone tell me when > > certificate is "trusted" in this context? (How to get rid this > > warning) or point to documentation/search keys A trusted certificate is a typically self-signed CA certificate stored in a file which is used to hold trusted certificates. -- VIktor.
Re: DH parameter reading in OPENSSL 3
On Wed, Jul 13, 2022 at 06:47:15PM +0200, Dirk Stöcker wrote: > > https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_dh.c#L148-L205 > > Thanks a lot. Works in principle now with one exception. The previous > approach worked for a file, where first comes the PEM certificate and > afterwards the DH params. The new approach only works when the file has > nothing than the DH params inside. Is there a chance to get that behaviour > back or do I need to load the file and strip the certificate myself? The work-around is to put the DH parameters first. Otherwise, you'd need to resort to the more general OSSL_STORE API, which loads objects of various types, and you can then ignore the ones you don't care for. Another option is to iterate through the PEM file via the generic PEM API, and then decode just the desired objects: https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L344-L378. -- Viktor.
Re: DH parameter reading in OPENSSL 3
On Wed, Jul 13, 2022 at 04:35:42PM +0200, Dirk Stöcker wrote: > when upgrading to openssl3 my code states that some functions are > deprecated in openssl 3, but even after reading documentation I was > unable to find a non-deprecated replacement. https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_dh.c#L148-L205 > Now it seems the default can be replaced by > > SSL_CTX_set_dh_auto(context, 1); This is preferred over all explicit parameter choices, as it allows the server and client to negotiate a common known-strong group. -- Viktor.
Re: error: wrong version number
On Sun, Jul 10, 2022 at 02:41:23PM +, loic nicolas wrote: > I am trying to connect my client to my server but I always receive an > error.(ssl3_get_record:wrong version > number:../ssl/record/ssl3_record.c:331) > > How can I get more information about the error and fix it? (the error > is probably in my client) Indeed, the client's packet to the server is not a TLS Record. > openssl s_server -accept 127.0.0.1:3000 -key server.key -cert server.cert -msg > > <<< ??? [length 0005] > 20 ae c0 2e d6 Whatever the client is doing, it isn't starting a TLS session with a TLS handshake record containing a TLS client HELLO. -- VIktor.
Re: baffled on old Red Hat Enterprise Linux 6 with OpenSSL 3.0.3
On Fri, Jun 10, 2022 at 09:43:45AM -0400, Dennis Clarke via openssl-users wrote: > I am surprised that people are not hitting this wall on all > platforms. Pushing out a new release jsut for an expired test > certificate seems a tad silly but perhaps ALL the test certs can > be updated at the same time. Whatever works. Most of the test certificates were generated via my "mkcert" script, which creates 100-year certificates, and will not expire until some time after 2316. The particular problem certificates were generated manually, by the author of the SCT (certificate transparency) code, and sadly were not created with nearly as long a lifetime. I hope their replacements don't have that issue. -- Viktor.
Re: How to figure out if .P12 is RSA or ECC crypted
On Thu, Jun 09, 2022 at 10:16:24AM +, Beilharz, Michael wrote: > I retrieve .P12 certificates, they can be RSA or ECC crypted PKCS#12 objects are encrypted with a *symmetric* password: 3DES, AES, ... Perhaps you're confusing the public key algorithm in the certificate (or corresponding private key) with the encryption algorithm of the PKCS#12 object? > so I offer two methods, to convert them into .PEMs. The extraction of PEM formatted (PKCS#8) private keys and certificate chains (a sequence of X.509 certificate objects) from a PKCS#12 object does not require any public key algorithm-dependent techniques. The same basic steps work for both RSA and ECDSA. > I would like to detect, if a P12 is RSA or ECC crypted, so that I > offer only one Method and the method itself decide the correct way to > convert the P12. What actual problem are you trying to solve? -- Viktor.
Re: using TLS (>1.2) with more than one certificate
On Tue, May 24, 2022 at 04:10:00PM +0100, Angus Robertson - Magenta Systems Ltd wrote: > I do see a lot of SSL connection errors in my logs, but assume these > are mostly hackers or trackers with software not able to support > TLS/1.2, usually with a blank SNI and ALPN and often no extensions in > the client hello. One had 'Versions: TLSv1.1, TLSv1.3 Key Share Data' > so got unsupported protocol. Various less popular, but still deployed SMTP servers are not updated nearly as often as desktop browsers, ... and some still support only RSA. Depending on where your users' mail comes from you may need to support RSA for SMTP. This is not a strong recommendation, but it is something to keep in mind. -- Viktor.
Re: Help needed with X509_STORE_CTX structure
On Mon, May 09, 2022 at 06:00:14AM +, Srinivas, Saketh (c) wrote: > I need to set the current_issuer field in an object of the > X509_STORE_CTX structure. Can any suggest the setter function for > this. You almost certainly don't *need* to do this. What is the actual high-level task you're trying to achieve. X509_STORE_CTX is used with X509_verify_cert(): https://www.openssl.org/docs/manmaster/man3/X509_verify_cert.html to verify a certificate chain. The "current_issuer" field is filled in so it can be read by callbacks, setting it in user code makes little sense. Note that the X509_STORE_CTX structure is not opaque, and you can just set its fields, but in this is case it is likely a bad idea to do that. > Also, current_crl_score and current_reasons also are needed to be 0 > for me. Can you suggest setters for these variables. Ditto. -- Viktor.
Re: X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS
On Tue, Apr 19, 2022 at 10:07:15PM -0400, Viktor Dukhovni wrote: > This is an apples/oranges dichotomy. "*" wildcards are "presented > identifiers" in the certificate. > > If the documentation is not sufficiently clear (too subtle) on this > point, would you like to suggest some text to clarify the documentation? > A pull request? Note that paragraph three of the DESCRIPTION reads: When name [bold font] starts with a dot (e.g. ".example.com"), it will be matched by a certificate valid for any sub-domain of name, (see also X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS below). where it should ideally be clear that we're talking about the peer name specified by the application (reference identifier in terms of RFC 6125), not a DNS-ID in the certificate (presented identifier). -- Viktor.
Re: X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS
On Tue, Apr 19, 2022 at 03:25:03PM -0700, Hal Murray wrote: > man X509_check_host says: >If set, X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS restricts name values >which start with ".", that would otherwise match any sub-domain in the >peer certificate, to only match direct child sub-domains. Thus, for >instance, with this flag set a name of ".example.com" would match a >peer certificate with a DNS name of "www.example.com", but would not >match a peer certificate with a DNS name of "www.sub.example.com"; this >flag only applies to X509_check_host. > > I haven't see the idea of ".example.com" being special in any of the RFCs > I've > been looking at. Can somebody give me a lesson in this area? You perhaps did not notice that this describes syntax in "reference identifiers" (arguments to SSL_set1_host(3), ...), rather "presented identifiers" (contents of the peer certificate). As such these a local matter (API detail) that lies outside any RFC. A verifier than asks for a specific hostname is not affected by this feature. But a verifier that asks OpenSSL to verify ".example.com" against a certificate is specifying a "fuzzy" match. > Is there any way to turn it off totally while still allowing * type wildcards? This is an apples/oranges dichotomy. "*" wildcards are "presented identifiers" in the certificate. If the documentation is not sufficiently clear (too subtle) on this point, would you like to suggest some text to clarify the documentation? A pull request? -- Viktor.
Re: freefunc - name clash with Python.h
> On 21 Jun 2020, at 1:20 pm, Dan Kegel wrote: > > Openssl should probably stop using generic identifiers like freefunc > in its header files, out of sheer self-defense. I'd long held an apparently minority opinion among OpenSSL team members that prototypes in header files MUST NOT name any variables, and should only mention their types, precisely to avoid this sort of issue. Thus, e.g.: int foo(char *, int); rather than: int foo(char *buf, int len); Variable names in header files are no substitute for documentation, and are all too prone to precisely this sort of conflict. -- Viktor.
Re: How does a client get the server's SAN/DNS strings
> On 17 Apr 2022, at 11:29 am, Michel wrote: > > What a beautiful source code ! > If only all software could be written like this ! The Postfix project aims for code quality, security and backwards compatibility over hastily deployed shiny new features. You'll find many examples of careful/correct use of OpenSSL in: https://github.com/vdukhovni/postfix/tree/master/postfix/src/tls The main "limitation" to keep in mind is that the Postfix concurrency model is multi-process no multi-thread. So issues related to thread-safety don't arise and are not addressed. -- Viktor.
Re: How does a client get the server's SAN/DNS strings
On Sat, Apr 16, 2022 at 03:02:16PM -0700, Hal Murray wrote: > openssl-us...@dukhovni.org said: > > Can you explain *why* you want the list of DNS names? > > Is this just for logging.. > > Yes, just for logging. https://github.com/vdukhovni/postfix/blob/postfix-3.5/postfix/src/tls/tls_client.c#L756-L794 -- Viktor.
Re: How does a client get the server's SAN/DNS strings
On Sat, Apr 16, 2022 at 01:18:57PM -0700, Hal Murray wrote: > I can get the subject and issuer with > X509_get_subject_name and X509_get_issuer_name > > I'm looking for something similar to get the SAN/DNS strings used to verify > that this certificate is valid for the hostname provided via SSL_set1_host > > Any API will be slightly complicated since there may be more than one SAN/DNS > string. Can you explain *why* you want the list of DNS names? What's wrong with letting OpenSSL doing the validation for you? Is this just for logging, or do you intend to supplant the built-in name checks? -- Viktor.
Re: CVE-2022-0778 - Impact of ECC cipher with valid server ECC certificate
On Sat, Mar 26, 2022 at 12:32:03PM +0530, Vipul Mehta wrote: > If we consider ECDHE_ECDSA cipher based TLS handshake, then it is possible > that the client can send invalid public session key to the server causing > the vulnerability. Is this assumption correct ? The CVE only affects situations in which the untrusted peer can specify malign "explicit" curve *parameters*, not just the public point. > If yes, then I think disabling ECC cipher suites should prevent the > vulnerability if we don't want to upgrade openssl considering there is no > other cryptographic operation except w.r.t. TLS. Unless I'm missing something, there's no need to disable ECC ciphers, since with TLS 1.0 through 1.2 the curve parameters are chosen by the server. With the TLS 1.3, the client typically sends a key share first, which consists of a named group and again a public point. There is no mechanism for conveying "explicit" ECC parameters https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.8 https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.8.2 So either way, TLS servers are safe if they don't solicit client certificates, or otherwise in some form consume X.509 SPKI public keys (which with ECC do signal either a named group or provide explicit parameters). -- Viktor.
Re: Verify signature usage
> On 21 Mar 2022, at 2:36 pm, buy wrote: > > It works great. Instead of using an actual signature.file, is there > a way to tell openssl to use a string instead? Use "bash" or a similar shell that supports <(cmd ...) pseudo-files. For a printable string signature: -signature <(printf "%s" "$sig") If the signature is binary data, perhaps: -signature <(echo $sig | openssl base64 -A -d) or whatever it takes to produce the desired content. -- Viktor.
Re: Certificate authority changes with OpenSSL
On Thu, Mar 17, 2022 at 07:51:43PM +0100, egoitz--- via openssl-users wrote: > I think that is the problem, the sha1. That's the specific issue being reported. > So... I have built Openssl 3.0.2 There's no reason for OpenSSL 3.0.2, that might just tighten the restrictions further. OpenSSL 1.0.0 and up all support SHA2-256, you can create and consume SHA-2 certificates with OpenSSL 1.1.1. > I have seen that the own CA uses sha1WithRSAEncryption signature > algorithm. Yes, fix that. > I assume this is one of the things to change, so I have planned to > convert the whole PKI, the whole CA to another supported Signature > algorithm that had no issues with SECLEVEL2. Just set the default digest to sha256, and reissue all the intermediate and leaf certificates. The root CA can stay unchanged, its self-signature is not relevant. > 1 - Is it possible to update a whole CA with 2048 bit public and private > keys (I used in req section of openssl.conf, the default_bits to 2048) > to a Signature algorithm that don't bother the SECLEVEL 2?. SHA2-256 is sufficient. > I mean to have two versions of the same certificate. One for SECLEVEL1 > and one for SECLEVEL2?. I preserve all csr and so It is isn't "the same certificate". You can issue new certificates, that all clients can verify, by using SHA2-256. > 2 - I was wondering too another question... although this is not urgent > now. If the CA key pair, is almost expiring what's the proper process of > doing what is supposed to be done?. I assume, it could be : Keys don't expired, certificates do. You can reissue a CA certiifcate with the same key and subject name, but a different expiration time and serial number. > But... I assume I would have to use a different CN for the new CA?. No, you would typically use the same CN if just extending the validity. > Perhaps is this same process the one I need to do for converting > certificates from SECLEVEL 1 friendly to SECLEVEL 2 friendly?. Certificate don't have seclevels, they have a signature algorithm, SHA2-256 has long been support by all clients. -- Viktor.
Re: openssl-users Digest, Vol 88, Issue 18
On Mon, Mar 14, 2022 at 12:47:26PM -0700, Edward Tsang via openssl-users wrote: > I guess I need to explicitly set X509_STORE_CTX_set_error(ctx, > X509_V_OK) before return 1 in the example if I need caller > SSL_get_verify_result to return X509_V_OK? Yes, but I'd like to strongly suggest that this is a bad idea. Instead, abort the handshake on errors you're unwiling to accept, and then the only possible errors at the conclusion of the handshake are those you're willing to accept. You can then still observe and log the fact that the handshake was not in fact fully authenticated, and an error condition was tolerated. Note that by setting the error condition to X509_V_OK you might be losing information about earlier error conditions which also returned "ok = 1", but are not intended to be acceptable at the conclusion of the handshake. This poses significate security risks. In other words, if sometimes (or always) return "ok = 1" even for error conditions that you don't intend to clear, by clearing "expiration" and treating the connection as verified on X509_V_OK you're opening up a major security hole. The only way to make this safe is to be sure to return "ok = 0" on all other error conditions. But, in that case, there's no point in doing anything drastic with SSL_get_verify_result(), any error conditions that did not terminate the handshake must have been acceptable. You're skating on thin ice, and need to think very carefully about possible subtle issues with your design choices. -- Viktor.
Re: Question about examples in openssl doc X509_STORE_CTX_verify_cb
On Mon, Mar 14, 2022 at 11:25:51AM -0700, Edward Tsang via openssl-users wrote: > https://www.openssl.org/docs/man1.1.1/man3/X509_STORE_CTX_verify_cb.html > > I am trying to figure out how this example works but it does not seem to > bypass the (use the second example of X509_V_ERR_CERT_HAS_EXPIRED) > > However the caller code > long res = SSL_get_verify_result( sslCtx ); still reports res NOT as > X509_V_OK, which it should be oper the example since it is returning as 1. This is correct and expected. Returning "ok = 1" from the verify callback allows the handshake to continue, rather than be aborted, but it does not and should not mark the certificate as verified. > I don't think I need to use X509_STORE_CTX_set_error(ctx, X509_V_OK); > before return 1 in the X509_STORE_CTX_verify_cb example. > Or am I missing something? You're missing something. It is best to not suppress the error code, since this will also mean that resumed sessions are unaware of the error, ... Rather if you want to tolerate expired certificates record and admit that error both in the callback and after the handshake. -- Viktor.
Re: SSL_ERROR_WANT_READ after the handshake
> On 12 Mar 2022, at 6:08 pm, loic nicolas wrote: > > After the handshake, is it really necessary to check SSL_ERROR_WANT_READ and > SSL_ERROR_WANT_WRITE? (whether on the server or client side) > I don't want to accept a renegotiation, is it really possible that OpenSSL > sends me these events without them being linked to a renegotiation? > > I did several tests on more or less long connections and I never receive them > but I would like to be sure. Yes, you can encounter WANT_READ or WANT_WRITE even after the handshake, especially when using non-blocking sockets. -- Viktor.
Re: Openssl s_client verify_ip usage on ip wildcard matching
On Fri, Mar 11, 2022 at 04:40:24PM -0800, Edward Tsang via openssl-users wrote: > Does verify_ip supports leftmost wildcard? I am not aware of any RFC specifying wildcard matching in iPAddress X.509 SANs, and no such feature is implemented in OpenSSL. The SAN syntax is raw binary data in network byte order with 4 bytes for IPv4 and 16 bytes for IPv6, with no place to signal a wildcard: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6 IP address SANs in certiificates must match exactly. -- Viktor.
Re: Multi root certs support
> On 11 Mar 2022, at 8:49 am, Tomas Mraz wrote: > > Yes, this is a fully supported scenario. > > You can even test it with the openssl s_server command - use -cert, - > key, and -cert_chain for the first certificate and -dcert, -dkey, and - > dcert_chain with the second one. Note that with e.g. SMTP, where some sites also publish DANE TLSA records, when multiple certificates are configured, multiple corresponding TLSA records need to be published: https://mail.sys4.de/pipermail/dane-users/2017-August/000416.html https://mail.sys4.de/pipermail/dane-users/2017-August/000417.html At the API level you can call `SSL_CTX_use_cert_and_key(3)` multiple times, once per algorithm. If `replace` is zero and keys for the same algorithm are provided more than once an error is reported. For example: https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_certkey.c#L152-L181 https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_use_cert_and_key.html The keys, cert and chain are copied by OpenSSL, so you need to free your copy when no longer needed. -- Viktor.
Re: is there any working example of how to use verify_hostname in command line?
> On 3 Mar 2022, at 11:55 pm, Edward Tsang via openssl-users > wrote: > > the openssl I'm using is in mac > openssl version -a > LibreSSL 2.8.3 LibreSSL is not OpenSSL. This is not the right forum for LibreSSL questions. -- Viktor.
Re: is there any working example of how to use verify_hostname in command line?
On Thu, Mar 03, 2022 at 08:05:34PM -0800, Edward Tsang via openssl-users wrote: > Ok here is what I tried but still complaining about unknown options > -verify_hostname > openssl s_client -connect google.com -CAfile etc/auth/cacert.pem > -verify_hostname google.com -verify_return_error Perhaps you're using some other "openssl" that isn't from the OpenSSL project, or an OpenSSL version that predates 1.0.2 which introduced the "verify_hostname" option. With the real OpenSSL 1.1.1 I get: $ openssl s_client -connect google.com:443 -CAfile /etc/ssl/cert.pem -verify_hostname google.com -verify_return_error -brief
Re: is there any working example of how to use verify_hostname in command line?
> On 3 Mar 2022, at 6:09 pm, Edward Tsang via openssl-users > wrote: > > openssl s_client -CApath . -CAfile ./cacert.pem -verify_hostname example.com > > All I get is "unknown option -verify_hostname > usage: s_client args" > > Have tried combinations of that and check out of doc... really not helping. You need to specify a server to connect to via the "-connect" option. It takes a hostname or IP address as a required argument, with an optional ":port" suffix. -connect www.example.com:443 -connect 192.0.2.1:443 -connect [::1]:443 ... You may also want "-brief" and "-verify_return_error". -- 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: Best Practice of Creating TLS Client /Server in C?
On Fri, Feb 11, 2022 at 09:13:05PM +, Joseph Chen via openssl-users wrote: > Could someone point me to some good reads or C code examples for > creating a TLS client/server with best practices? Best practices vary between application applications. For example, a Web browser retrieving an HTTPS URL and an MTA SMTP client doing opportunistic STARTTLS face rather different requirements. In Postfix, you'll find clean, well commented code that handles the SMTP use-case, and supports strict verification modes, but defaults to unauthenticated TLS. So you'd have to understand which knobs to set to get the behaviour you want. The upside is that the range of possible behaviours is broad, so it can be tuned to meet the needs of most applications. The downside, is that there's a lot of application code there above OpenSSL to support all those options. In particular the resumption support depends on a peer application service that caches serialised sessions and handles session ticket rollover. The SNI support uses key/value lookup tables, where the table value is a serialised PEM file with the private key and cert chain. Loading of private key and cert chain is atomic when both are in the same file (file opened just once)... All this requires custom code. So this codebase is a "maximal viable" variant. If you want "minimal viable", you'll need to look elsewhere. https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_client.c https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_server.c -- Viktor.
Re: [OpenSSL 1.1.1l] Hi Team, my SSL/TLS server crashed with the attached call stack. Your advice will be highly appreciated.
On Thu, Feb 10, 2022 at 11:48:06PM +, Ma Zhenhua wrote: > Hi Team, > > My SSL/TLS server crashed with the following call stack. > I'm using OpenSSL 1.1.1l. I compared 1.1.1l with 1.1.1 master branch and > didn't find related fixes in crypto/asn1. > Your advice will be highly appreciated. You need to run your code under valgrind, and see where the heap is being corrupted. Most likely your application code freed something it did not own, or double-freed something it did own. -- VIktor.
Re: How to distinguish between encrypted/unencrypted key in a PEM file
> On 26 Jan 2022, at 9:14 am, Bartlomiej wrote: > > I have a PEM file on the device which can contain an encrypted/non-encrypted > private key. When it's encrypted, it's using PBES/PBKDF. The file is accessed > from a C++ application which uses the OpenSSL library. If the key is > encrypted, then it should be PKCS#8, but checking it is PKCS#8 by using e.g. > `PEM_read_PKCS8` is not enough to confirm it is actually encrypted, since an > unencrypted key can also be stored as PKCS#8. Is there a way to check whether > the key is encrypted or not using OpenSSL APIs? If nobody else can suggest anything better, and without an exhaustive check for higher-level alternatives, I can suggest the low-level type- agnostic PEM_read_bio(3) that reads a PEM header and data, leaving it up to you to interpret the data as you want, based on the PEM header. For example: https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_dane.c#L1189-L1219 In the case of PKCS8, you'd be looking for: openssl/pem.h:# define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" as opposed to one of: openssl/pem.h:# define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" openssl/pem.h:# define PEM_STRING_RSA "RSA PRIVATE KEY" openssl/pem.h:# define PEM_STRING_DSA "DSA PRIVATE KEY" openssl/pem.h:# define PEM_STRING_PKCS8INF "PRIVATE KEY" openssl/pem.h:# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" -- Viktor.
Re: TLSv1.2 Distinguished Names Length 0 / how to set it
On Wed, Jan 19, 2022 at 05:21:27PM +0100, Olivier Germain via openssl-users wrote: > We have a requirement to implement the Distinguished Name in the response > received by the client. Hopefully I am ok. More accurately, you're being asked to send a suitable non-empty list of "Distinguished Names" in server "certificate request" extensions, when soliciting client certificates. This can be necessary to, e.g., solicit client certificates from Java applications, which select the certificate to use based on the names suggested by the server. > How can I set in my SSL code the value for the distinguished Name? Something along the lines of the below, which extracts the subject DNs from a PEM file with trusted issuer (root CA) certificates: if (CAfile) { STACK_OF(X509_NAME) *calist = SSL_load_client_CA_file(CAfile); if (calist != NULL) SSL_CTX_set_client_CA_list(ctx, calist); } The operator of the server should be able to configure a file of trusted client cert issuers separately from the default list of trusted issuers. This would ideally hold just one or a few CAs actually used to issue client certificates trusted by the server in question. Note the documented ownership transfer: SSL_CTX_set_client_CA_list() sets the list of CAs sent to the client when requesting a client certificate for ctx. Ownership of list is transferred to ctx and it should not be freed by the caller. There are other ways to construct a stack of CA X.509 names, but loading them from a PEM file of CA certs is typically the simplest option. -- Viktor.
Re: SSL_CTX_set_tlsext_ticket_key_evp_cb
On Sun, Dec 05, 2021 at 10:35:01PM +, Jeremy Harris wrote: > The docs at > > > https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_tlsext_ticket_key_evp_cb.html > > say "returns 0 to indicate the callback function was set" > > > The code (6d770c5ba36d43f4): > > int SSL_CTX_set_tlsext_ticket_key_evp_cb > (SSL_CTX *ctx, int (*fp)(SSL *, unsigned char *, unsigned char *, > EVP_CIPHER_CTX *, EVP_MAC_CTX *, int)) > { > ctx->ext.ticket_key_evp_cb = fp; > return 1; > } > > > (I suspect from my application code comments that > SSL_CTX_set_tlsext_ticket_key_cb() may suffer the same) Looks like you're right. The documentation is in error, but given the functions in question just set a pointer, I'm presently ignoring their return values. Still, the docs should be correct. -- Viktor.
Re: Need Replacement for Deprecated function.
On Sun, Dec 05, 2021 at 09:59:34PM +, Jeremy Harris wrote: > >> The reference example in > >> https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_tlsext_ticket_key_cb.html > >> > >> uses OSSL_MAC_PARAM_KEY and OSSL_MAC_PARAM_DIGEST. > >> > >> So does the code in master as of 6d770c5ba3. But I don't see definitions > >> for them > > So... how does that code compile? It works fine for me: https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls.h#L78 https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls.h#L87-L94 #ifndef OPENSSL_VERSION_PREREQ #define OPENSSL_VERSION_PREREQ(m,n) 0 #endif https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_server.c#L155 #if OPENSSL_VERSION_PREREQ(3,0) #include /* EVP_MAC parameters */ #endif https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_server.c#L302-L339 > Where is that macro defined? -- Viktor.
Re: (OpenSSL bug please fix) Re: Need Replacement for Deprecated function.
On Sat, Dec 04, 2021 at 12:53:34AM -0500, Viktor Dukhovni wrote: > Actually, no, not your fault at all. The implementation in libssl is > borked. Please open a ticket. I took care of opening the ticket: https://github.com/openssl/openssl/issues/17196 -- Viktor.
(OpenSSL bug please fix) Re: Need Replacement for Deprecated function.
On Fri, Dec 03, 2021 at 07:05:43PM +, Jeremy Harris wrote: > > EVP_PKEY_get_bits() should be equivalent to DH_bits() (for a DH > > file). I would definitely double-check that you are not mis-loading > > something. > > OK; this was indeed my fault. Actually, no, not your fault at all. The implementation in libssl is borked. Please open a ticket. > One minor docs item: >https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set0_tmp_dh_pkey.html > > says >"Ownership of the dhpkey value is passed to the SSL_CTX or SSL >object as a result of this call, and so the caller should not free >it if the function call is succesful." Yes, ***if the call is successful**. Unsuccessfull calls should not ever take ownership or have any side effects other than reporting failure. The implementation is: int SSL_set0_tmp_dh_pkey(SSL *s, EVP_PKEY *dhpkey) { if (!ssl_security(s, SSL_SECOP_TMP_DH, EVP_PKEY_get_security_bits(dhpkey), 0, dhpkey)) { ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL); --Wrong!--> EVP_PKEY_free(dhpkey); return 0; } EVP_PKEY_free(s->cert->dh_tmp); s->cert->dh_tmp = dhpkey; return 1; } > It's not quite clear what the onwership for a failing call is. > Experiment shows that an EVP_free() after a fail causes a crash, > at least for a "dh key too small" error. This is a booby trap and needs to be fixed. You're not the only the one to bit by this. This even affects existing code in OpenSSL: ssl/ssl_conf.c:cmd_DHParameters() ... if (cctx->ctx != NULL) { if ((rv = SSL_CTX_set0_tmp_dh_pkey(cctx->ctx, dhpkey)) > 0) dhpkey = NULL; } if (cctx->ssl != NULL) { if ((rv = SSL_set0_tmp_dh_pkey(cctx->ssl, dhpkey)) > 0) dhpkey = NULL; } end: EVP_PKEY_free(dhpkey); BIO_free(in); return rv > 0; } The key is freed when the call fails. This is a bug in: commit 163f6dc1f70f30de46a68137c36e70cae4d95cd8 Author: Matt Caswell Date: Thu Oct 15 16:45:54 2020 +0100 Implement a replacement for SSL_set_tmp_dh() -- Viktor.
Re: Need Replacement for Deprecated function.
On Wed, Dec 01, 2021 at 03:54:15PM +, Jeremy Harris wrote: > On 29/11/2021 15:10, Matt Caswell wrote: > > SSL_CTX_set0_tmp_dh_pkey() > > "Deprecated since OpenSSL 3.0" > > Is there a non-deprecated interface? I've reworked the DH support in Postfix for OpenSSL 3.x compatibility, without use of any deprecated interfaces. I now prefer/recommend the use "auto" DH parameter selection: https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_dh.c#L140-L230 -- Viktor.
Re: OpenSSL 1.1 on OSX
On Sat, Nov 20, 2021 at 01:38:39PM +1100, Grahame Grieve wrote: > I agree it's sure not a core openSSL issue. But surely lots of people > want to use openSSL in cross platform apps and openSSL is interested > in adoption issues? Most of the users here are building applications that are not notarised, and so work with the upstream builds. > Anyway, it looks like I now have to figure out how to maintain a > custom build of openSSL :-( It shouldn't be too difficult to execute the build, once you've figured out the actual requirements. Apparently you need to make sure that signed code has very explicit dependencies, which makes some sense, so the libraries bundled with the application need to be built in a way that can be verified along with the application. My best guess is that Apple are not specifically picking on OpenSSL here, and similar issues would arise with any other libraries you'd want to package with your application. Good luck. Feel free to share your findings. Perhaps someone will then help you find a way to improve on them, or to add a template to the build to support this going forward... -- Viktor.
Re: OpenSSL 1.1 on OSX
On Sat, Nov 20, 2021 at 06:14:30AM +1100, Grahame Grieve wrote: > And the rule for that is that all code your application uses must be > signed either by you or by apple. I can include both openSSL dylibs in > my .app package, and sign all that, but the way libssl loads libcrypto > seems to not meet those rules - which specifically exclude symlinking > and which specifically prohibit loading libcrypto without specifying a > specific version. Which means you need to build libssl in such a way that it depends explicitly on the corresponding versioned build of libcrypto. That is you'll need to tweak the Darwin Configuration template to specify some additional linker options or other relevant settings. This is not an Apple Developer community, you're perhaps better off asking on an Apple forum, this is not an OpenSSL issue. You have * Application X -> * Needs Library Y -> * Needs Library Z you need to know how to build Library Y so that it is compatible with Apple's packaging requirements. Perhaps someone has done that for MacOS, but they might not be reading this list... -- Viktor.
Re: OpenSSL 1.1 on OSX
On Fri, Nov 19, 2021 at 05:36:24PM +1100, Grahame Grieve wrote: > It's very definitely something active that OSX is doing. Here's an OSX > error generated: > > System Integrity Protection: enabled > > Crashed Thread:0 Dispatch queue: com.apple.main-thread > > Exception Type:EXC_CRASH (SIGABRT) > Exception Codes: 0x, 0x > Exception Note:EXC_CORPSE_NOTIFY > > Application Specific Information: > abort() called > Invalid dylib load. Clients should not load the unversioned libcrypto > dylib as it does not have a stable ABI. Well, I think that's evidence of confusion about which "libcrypto" to load. It sure seems that you're trying to load the default system libcrypto, not the one in the application bundle. You should probably arrange to "salt" the names of the libssl and libcrypto libraries used by your application, so that there can't be any confusion with the platform's libssl and libcrypto. May also need to do something to avoid symbol name collisions, but I haven't looked into how that works on Darwin, so can't offer specific advice. -- Viktor.
Re: OpenSSL 1.1 on OSX
On Fri, Nov 19, 2021 at 04:31:26PM +1100, Grahame Grieve wrote: > I'm trying to get my application that uses openSSL 1.1 running on OSX. I've > installed them using homebrew, but I can't get past Apple's gates around > blocking use of openSSL. I don't think they're actively doing blocking here, though I could perhaps be wrong... > I've copied both dylibs into my app /Contents/MacOS folder, and signed > both of them, and I load them from the that location, but OSX still > blocks loading. More accurately I think, the libraries fail to load. > It actually blocks loading libssl.1.1.dylib, with a message about libcrypto > - presumably libssl has a non-version dependence on libcrypto that OSX is > blocking? The problem is likely that "libssl" not built to locate "libcrypto" relative to its own location, but rather expects to find it at a fixed location. This would be some MacOS-specific instance of setting the runpath to $ORIGIN on ELF systems. With OpenSSL installed at a fixed location, OpenSSL is working just fine for me (and of course in HomeBrew, ...). So the issue most probably the inability of "libssl.dylib" to find "libcrypt.dylib", not because of some policy enforcement by Apple's evil overlords, but simply because the runtime linker does not expect to look in the location where you have libcrypt installed. The only thing that gives me some pause is Whether or not notarisation also complicates relocation, but presumably applications can ship shared libraries with the application code without running into major obstacles. Perhaps the presence of LibreSSL on MacOS is another complication, but that libssl and libcrypt should have different version suffixes, and should not get in the way, provided that MacOS has something akin to symbol versioning, to allow separate API versions of the same library to exist in a process side by side without getting in each other's way. If the symbol namespace in MacOS is "flat", then you may indeed run into trouble because of symbol conflicts between the real OpenSSL and the LibreSSL fork. Good luck. -- Viktor.
Re: “EC PUBLIC KEY”
On Wed, Nov 17, 2021 at 11:11:58AM -0500, Felipe Gasper wrote: > Does OpenSSL intend to handle EC public keys that in PEM begin “BEGIN EC > PUBLIC KEY”? I doubt it, but there is: $ openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:prime256v1 | openssl ec read EC key writing EC key -BEGIN EC PRIVATE KEY- MHcCAQEEIDvaIBqlCepZmpLChB7wW1aMbecIsw79AftoaZttrdaEoAoGCCqGSM49 AwEHoUQDQgAE0XMziiLRVpKP/jNklqzZqejJKgcK+TQ9wynz3etCRqOq8hzW24VG PY+ORzD9LJqTMQF7NJytxR4vcCVcrpuXGg== -END EC PRIVATE KEY- There is no correspoding EC-specific PEM public key form in OpenSSL. You should be using the algorithm agnostic formats. -- Viktor.
Re: “EC PUBLIC KEY”
On Wed, Nov 17, 2021 at 10:37:01PM -0500, Felipe Gasper wrote: > It came from my own (very incomplete) crypto implementation. > (https://github.com/FGasper/p5-Crypt-Perl) It looks like I just had > the wrong idea about EC public keys back-when. > > Funny thing is that the “EC PUBLIC KEY” that I was outputting is the > same structure as a normal SPKI ECC public key; I just had the wrong > header (and, when parsing, thought there were 2 formats to check for). OpenSSL source in include/openssl/pem.h contains: # define PEM_STRING_X509_OLD "X509 CERTIFICATE" # define PEM_STRING_X509 "CERTIFICATE" # define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" # define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" # define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" # define PEM_STRING_X509_CRL "X509 CRL" # define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" # define PEM_STRING_PUBLIC "PUBLIC KEY" # define PEM_STRING_RSA "RSA PRIVATE KEY" # define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" # define PEM_STRING_DSA "DSA PRIVATE KEY" # define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" # define PEM_STRING_PKCS7"PKCS7" # define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" # define PEM_STRING_PKCS8"ENCRYPTED PRIVATE KEY" # define PEM_STRING_PKCS8INF "PRIVATE KEY" # define PEM_STRING_DHPARAMS "DH PARAMETERS" # define PEM_STRING_DHXPARAMS"X9.42 DH PARAMETERS" # define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" # define PEM_STRING_DSAPARAMS"DSA PARAMETERS" # define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" # define PEM_STRING_ECPARAMETERS "EC PARAMETERS" # define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" # define PEM_STRING_PARAMETERS "PARAMETERS" # define PEM_STRING_CMS "CMS" The PEM formats supported should be at most these. -- Viktor.
Re: X509_get_pubkey() in OpenSSL 3.0?
On Wed, Nov 03, 2021 at 08:32:43PM +, Jason Schultz wrote: > To summarize, at application start time I read in all of the > certificates in /etc/ssl/certs/ to a trusted store created with > X509_STORE_new(). > > When getting ready to "start" a server (again, leaving a lot of > specifics out to avoid getting bogged down in details), I'm doing the > processing in the previous messages on this thread. Here are the API > calls again, with the changes previously discussed: > > ctx = SSL_CTX_new_ex(non_fips_libctx, NULL, TLS_method()); > SSL_CTX_use_PrivateKey_file(ctx,,SSL_FILETYPE_PEM); > SSL_CTX_use_certificate_file(ctx,,SSL_FILETYPE_PEM); > SSL_CTX_check_private_key(ctx); > mycert = SSL_CTX_get0_certificate(ctx); > pkey = X509_get_pubkey(mycert); > > After that's done, I make several OpenSSL calls to get things set up the way > I want: > > param = X509_VERIFY_PARAM_new(); > X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_PARTIAL_CHAIN); > X509_STORE_set1_param(ssl_trusted_certs, param); > X509_VERIFY_PARAM_free(param); > > I call these to treat intermediate certs as trust-anchors, so I can > trust an intermediate certificate; ssl_trusted_certs is the > aforementioned X509_STORE. I am puzzled as to you working so hard (writing a bunch of low-level trust-store and chain construction code) to construct at runtime, what could be created statically at chain file construction time. Especially if you stick with best practice and keep certificate lifetimes reasonably short (~90 days or less, not years). The certificate chain file constructed at the time the certificate is issued should work unchanged for the lifetime of the certificate, and the server applications can avoid having to execute any chain construction or verification code. Yes, you're asking somewhat "interesting" questions, in that, e.g., I am not up to speed on all the changes in 3.0.0, and perhaps there are indeed some issues around legacy SHA1 signatures, but I do suspect that a more productive use of your time is likely to reconsider the decision to work at such a low layer. It may be wiser to find a way to "unask" the question, i.e. make it moot, by avoiding rather than solving the problem. > I'm not clear on if the calls I've added to > SSL_CTX_get0_certificate(ctx) and X509_get_pubkey(), the latter of > which was being used before, are what's causing the problem. The > OpenSSL error queue shows the following on the > SSL_CTX_build_cert_chain() failure: > > 00B741558E7F:error:0308010C:digital envelope routines:(unknown > function):unsupported:crypto/evp/evp_fetch.c:346:Global default library > context, Algorithm (SHA1 : 96), Properties () > 00B741558E7F:error:0372:digital envelope routines:(unknown > function):decode error:crypto/x509/x_pubkey.c:444: > 00B741558E7F:error:0372:digital envelope routines:(unknown > function):decode error:crypto/x509/x_pubkey.c:444: > 00B741558E7F:error:0580006C:x509 certificate routines:(unknown > function):unable to get certs public key:crypto/x509/x509_vfy.c:1986: > 00B741558E7F:error:0A86:SSL routines:(unknown function):certificate > verify failed:ssl/ssl_cert.c:905:Verify error:unspecified certificate > verification error I haven't seen these before, your guess is as good as mine. -- Viktor.
Re: X509_get_pubkey() in OpenSSL 3.0?
On Wed, Nov 03, 2021 at 12:38:51PM +, Jason Schultz wrote: > In any case, things appear to be working now, but I'm hitting an issue > later on when calling SSL_CTX_build_cert_chain(). I working on > debugging that, I may have to start yet another thread later. Your mistake is probably in loading a certificate file, rather than a certificate chain file. With the latter, you'd also pick up any associated intermediate issuer certificates (e.g. from certbot's "fullchain.pem"). With the intermediate certificates thus obtained, you're far more likely to be able to verify the completely server's chain relative to some trust store with exclusively or mostly just a bunch of root CAs. I'd in fact recommend not rebuilding the provided chain, but just observing whether it is complete, the user may have good reasons for going with some alternative sequence of issuer CAs (e.g. to support old Android devices, as with e.g. current Let's Encrypt redundant cross cert). Therefore, per: SSL_CTX_build_cert_chain() builds the certificate chain for ctx. Normally this uses the chain store or the verify store if the chain store is not set. If the function is successful the built chain will replace any existing chain. The flags parameter can be set to SSL_BUILD_CHAIN_FLAG_UNTRUSTED to use existing chain certificates as untrusted CAs, SSL_BUILD_CHAIN_FLAG_NO_ROOT to omit the root CA from the built chain, SSL_BUILD_CHAIN_FLAG_CHECK to use all existing chain certificates only to build the chain (effectively sanity checking and rearranging them if necessary), the flag SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR ignores any errors during verification: if flag SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR is also set verification errors are cleared from the error queue. Details of the chain building process are described in "Certification Path Building" in openssl-verification-options(1). I'd set the flags to: SSL_BUILD_CHAIN_FLAG_UNTRUSTED | SSL_BUILD_CHAIN_FLAG_CHECK if you're sure the service is not DANE TLSA enabled, and there's definitely good reason to omit the root CA from the chain, or you provide a configuration to let the user make the choice, you can also add: SSL_BUILD_CHAIN_FLAG_NO_ROOT which is often, but not always appropriate, and should ideally not be unconditionally hardcoded. Be sure to clear the error queue before starting, and after reporting any errors observed. -- Viktor.
Re: X509_get_pubkey() in OpenSSL 3.0?
On Tue, Nov 02, 2021 at 08:28:01PM +, Jason Schultz wrote: > Victor- > > I can't seem to find any documentation on SSL_CTX_get0_privatekey(), > but by the name of it, it sounds like it's getting the private key; > I'm trying to get the public key. It does appear to be "under-documented" (i.e. not at all), perhaps that could be addressed. Note that you can get a public key from the private key. > That said, I should probably explain more of why I'm doing what I'm > doing, because there may be an easier way all together. Basically, we > allow configuring RSA or EC certificates/keys, and I want to get the > public key so I can check the type of key with a call to: > > EVP_PKEY_base_id(pubkey); Which you can equally get from the private key, but there's also: SSL_CTX_get0_certificate(sadly also "under-documented") which means that you certainly don't need to read the PEM file again. > So maybe there's a better way? After I call: > > SSL_CTX_use_certificate_file(ctx,,SSL_FILETYPE_PEM); > > Is there an API I can call passing the ctx that will tell me what type > of certificate is in use for that ctx? Or something else along those > lines? Also once you have an (SSL *) handle you can call SSL_get_certificate(3) which is documented, and proceed from there. > It's very possible I'm overcomplicating things with the fopen(), > PEM_read_X509(), X509_get_pubkey() sequence, so any suggestions on how > to better accomplish this verification are welcome. Yes. Query the data you already have in memory. Note that a context can be configured with *both* an RSA certificate chain *and* an EC certificate chain. The above functions return the one most recently loaded, but a handshake with a peer may select one of the other chains. Most applications only load keys for just one algorithm, but in general more may be present. It is surprising that you care which algorithm is in cert/keys. So long as it loads, why does it matter? If you want to log data for each handshake, at that point you can use SSL_get_certificate(3) for the cert actually selected by this handshake on the local end: https://github.com/vdukhovni/postfix/blob/master/postfix/src/tls/tls_misc.c#L950-L953 -- Viktor.
Re: X509_get_pubkey() in OpenSSL 3.0?
On Tue, Nov 02, 2021 at 07:42:15PM +, Jason Schultz wrote: > I thought I should start a new thread since this question was buried in my > "FIPS" thread and I dont' think it has anything to do with FIPS and OpenSSL > providers. I'm hitting another problem that I think is related to the > migration to OpenSSL 3.0, as this code works with OpenSSL 1.1.1 (and 1.0.2 > before it). When looking at the documentation pages for 1.1.1 vs 3.0, I'm not > seeing any differences between the OpenSSL APIs I'm calling in the 2 > different release levels. > > Here is the sequence, I'm basically setting up my certificate and private > key, both in PEM format, for the server, then I need to extract some > information from them: > > ctx = SSL_CTX_new_ex(non_fips_libctx, NULL, TLS_method()); > SSL_CTX_use_PrivateKey_file(ctx,,SSL_FILETYPE_PEM); > SSL_CTX_use_certificate_file(ctx,,SSL_FILETYPE_PEM); > SSL_CTX_check_private_key(ctx); > fp = fopen(, "r"); > mycert = PEM_read_X509(fp, NULL, 0, NULL); > pkey = X509_get_pubkey(mycert); Without addressing the question of why you're unable to get the public key handle from the certificate, why not just: pkey = SSL_CTX_get0_privatekey(ctx){ and skip reading the cert again? -- Viktor.
Re: Client side session handling
On Wed, Oct 13, 2021 at 11:57:14PM +, Jason Schultz wrote: > I'm somewhat familiar with the reference count stuff from reading the > doc on these (and other) functions. But it sounds like the behavior > I'm seeing is expected, and OpenSSL is doing the actual free of the > SSL_SESSION when the SSL_CTX is freed. That's plausibly the case, barring bugs in your application, yes either freeing some handle too many or too few times. -- Viktor.
Re: Client side session handling
On Wed, Oct 13, 2021 at 02:32:10PM +, Jason Schultz wrote: > The confusing part is that given everything above, when I free the > SSL_CTX associated with these connections/sessions, I see the remove > callback function get called again for client-side sessions that I > already called SSL_SESSION_free() on. Is this normal behavior? Is > there something else I’m missing? OpenSSL SSL_SESSSIONS are reference-counted. This is typical of a number of similar sufficiently complex structures for which it makes more sense to bump a reference counter than to make a copy. The SSL_SESSION_free(3), X509_free(), and various other calls just decrement the reference counter, with the object only actually freed once the counter reaches 0. Various functions (though not all, as documented for each function) that return such objects to the application increment the refernce counter (say initially from 1 to 2), and the application is then responsible for decrementing it. THe object is finally freed when any internal reference is released (if that happens last). The internal store of client-side sessions is not used by OpenSSL for anything other than asking the application to remove sessions when the cache exceeds some limit, the application still needs its own cache lookup mechanism and its own separat cache (of the same shared by reference count underlying objects), all the OpenSSL cache is doing for you is "helping" you keep the cache size bounded. In Postfix we serialise session objects into a cache in which they are not shared with OpenSSL and manage expunging stale sessions independently of OpenSSL. We therefore tell OpenSSL to not bother maintaining an internal cache. SSL_CTX_set_session_cache_mode(client_ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE | SSL_SESS_CACHE_NO_AUTO_CLEAR); All the work of managing session storage and lookup is done by the callback: SSL_CTX_sess_set_new_cb(client_ctx, new_client_session_cb); There's no remove callback, we handle cache management outside OpenSSL.. -- Viktor.
[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: OpenSSL 3.0.0 enabling SSLv3 support
On Thu, Oct 07, 2021 at 09:38:30AM -0500, Mark Hack wrote: > Added to all the weaknesses in SSLv3, the only supported cipher suites > are either vulnerable or deprecated and not advisable. If we set aside browsers where CBC padding oracles are a problem, the below are in practice still reasonably strong in most other applications. ECDHE-RSA-AES256-SHASSLv3 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1 ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1 DHE-RSA-AES256-SHA SSLv3 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1 AES256-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA1 ECDHE-RSA-AES128-SHASSLv3 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1 ECDHE-ECDSA-AES128-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1 DHE-RSA-AES128-SHA SSLv3 Kx=DH Au=RSA Enc=AES(128) Mac=SHA1 AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 And yet, SSLv3 should still not be used, because it does not support extensions, so no SNI, no protection against insecure renegotiation, ... -- Viktor.
Re: OpenSSL 3.0.0 enabling SSLv3 support
On Tue, Oct 05, 2021 at 03:49:48PM -0700, Kory Hamzeh wrote: > It looks like SSLv3 is not built by default in OpenSSL 3.0.0. At least > SSLv3_method() is not define, and looking at the conditional > compilation of that function, it makes sense. > > What command line option do I pass the Configure script to enable it? > I tried enable-sslv3 and enable-SSLv3. It complained about both. I > need to compile some old code (Python 2.7) which we will abandon soon. Don't enable SSLv3 in OpenSSL 3.0, that's not doing anyone a favour. Better to instead build the code in question against OpenSSL 1.1.1, if SSLv3 actually needs to be *used*. It is not a problem to install both OpenSSL 1.1.1 and OpenSSL 3.0 side-by-side (shared libraries) on systems with support for symbol versioning. If the only purpose of SSLv3 is to get code to compile, that will not in fact ever run, or that can reasonably just return an error when it runs, you can enable the method stubs, without enabling support for the protocol: ./Configure enable-ssl3-method ... The default is to disable both "ssl3" and "ssl3-protocol" and I would strongly encourage you to not enable both. Nobody should be actually using SSLv3 anymore, but exporting function stubs that will error out makes some sense if required to support toolkits that wrap the OpenSSL API and still want to expose SSLv3 methods. -- Viktor.
Re: SSL_CTX_set_verify uses the "wrong" certificate chain (cross signed certificate )
On Sun, Oct 03, 2021 at 09:33:29PM +0200, Alex Robuchon wrote: > > Not quite, a candidate chain is constructed from whatever certificates the > > peer (server in your case) provided, and then passed to the callback with > > "preverify_ok" set to false (for the top certificate), because the chain is > > not trusted. > > This confuses me a little bit because I thought the callback function set > with *SSL_set_verify* would have the "trusted first" valid chain. But there is no trust store configured, so trust first is a no-op. The constructed chain consists entirely of certificates from the peer, and last certificate in the chain (the ultimate issuing CA) is still not trusted, so preverify_ok = 0. > Are you sure you are not speaking as if eventmachine was using the > *SSL_CTX_set_cert_verify_callback* ? I rewrote the OpenSSL chain construction code for OpenSSL 1.1.0. Yes, I am sure. > - *build_chain* that will apply the trusted first algorithm and replace the > certificate chain passed by the server with the valid one ( if found ). The code in eventmachine does not configure any trusted certificates for the SSL_CTX handles used to create the SSL connections. So trusted-first is a no-op. > - *internal_verify *which now has the new chain and will call *verify_callback > *( the callback function passed to SSL_set_verify ) for every certificate > in this new chain in reverse order. You don't have to explain the code to me. :-) > > But given all the evidence before me, I'd want to delete that code and > > never see it again. > > I hear you :). That code is beyond repair, it needs to be thrown out, and replaced with ground up by the book TLS connection establishment. #1. No compiled in private keys #2. Configure the SSL_CTX with the desired list of trust anchors #3. Reuse the SSL_CTX for multiple connections that share the same trust and other general settings #4. Prior to SSL_connect(), tell the SSL library what hostname you want to verify via SSL_set1_host(3). Let OpenSSL do all the heavy lifting of certificate and name checks. #5. DO NOT attempt to override certificate chain verifiction in the verify callback. Use the verify callback only for logging or similar diagnostic purposes. #6. Return "preverify_ok" unmodified, unless your application is doing opportunistic unauthenticated TLS, or wants to complete the handshake even on verification failure, and then gracefully tear down the application-layer session with the peer (after checking the verification status at connection completion). If preverify_ok is false (0), OpenSSL chain verification failed, your application is unlikely to do better. Return 0, and the TLS handshake will be aborted, you can log the error reason, chain depth, ... in the verify callback. -- Viktor.
Re: SSL_CTX_set_verify uses the "wrong" certificate chain (cross signed certificate )
> On 3 Oct 2021, at 12:33 pm, Alex Robuchon > wrote: > > So I suppose openssl skip the part that is supposed to build the chain when > no store is configured. Not quite, a candidate chain is constructed from whatever certificates the peer (server in your case) provided, and then passed to the callback with "preverify_ok" set to false (for the top certificate), because the chain is not trusted. But the evenmachine callback ignores "preverify_ok" and goes through the motions of doing some sort of verification of each certificate. Ultimately, it will attempt to "verify" the leaf certificate, and if it can somehow do a fair job of that (by building its own chain, checking all the signatures, doing the name checks (for a name that does not appear to be passed to the verification function), then in theory the checks at depths above 0 are just silly opportunities to fail and the EE cert check would be enough. But given all the evidence before me, I'd want to delete that code and never see it again. -- Viktor.
Re: SSL_CTX_set_verify uses the "wrong" certificate chain (cross signed certificate )
On Sun, Oct 03, 2021 at 01:54:44PM +0200, Alex Robuchon wrote: > Thanks for the detailed answer. > > From strace I can see that I'm using /lib/x86_64-linux-gnu/libssl.so.1.1 > > When I use the eventmachine lib that uses the wrong cert chain I can see > with strace : Run as far away from eventmachine as you can. The very first thing you see in the code is a compiled in default "private key" (for all the world to share). https://github.com/eventmachine/eventmachine/blob/5cac87805f26b5cdc29eca713871c3374131d786/ext/ssl.cpp#L30-L123 Though applications can override these, and supply actual private keys, it does not get better from there... The comments in the code show the author punting on understanding the OpenSSL API and just guessing what to do. Indeed the code creates SSL_CTX objects without specifying either the default or explicit trust stores. The real disaster is in: https://github.com/eventmachine/eventmachine/blob/5cac87805f26b5cdc29eca713871c3374131d786/ext/ssl.cpp#L675-L698 with a completely broken SSL verification callback, that completely ignores all errors from the chain construction and signature verification code, and just attempts to "verify" each certificate in *isolation*. https://github.com/eventmachine/eventmachine/blob/5cac87805f26b5cdc29eca713871c3374131d786/ext/ssl.cpp#L693-L697 This means: * No verification of chain signatures * No verification of path constraints * No verification of name constraints * No hostname checks. * ... This code was written by someone too clueless to know what they're doing and too lazy to bother to learn. DO NOT USE IT. Do whatever it takes to never rely on this code again. Even abandon Ruby if that's what it takes... -- Viktor.
Re: SSL_CTX_set_verify uses the "wrong" certificate chain (cross signed certificate )
On Sat, Oct 02, 2021 at 06:21:00PM +0100, Angus Robertson - Magenta Systems Ltd wrote: > > Yes. To make things even more complex, a few sites also have an > > older version of R3 that is directly signed by the DST root: > > > > - leaf <- R3 <- DST Root CA X3 (self-signed) > > > > but that's far from common at this point. > > That old R3 [CA] was issued last winter and got installed in Windows > Server 2018 intermediate stores then, and was still being sent out on > 29th and 30th, despite expiring on 29th. Not just Windows, at least one Unix system running Postfix is still vending a chain with the R3 signed by DST that expired on 2021-09-29: issuer=O = Digital Signature Trust Co., CN = DST Root CA X3 subject=C = US, O = Let's Encrypt, CN = R3 notBefore=Oct 7 19:21:40 2020 GMT notAfter=Sep 29 19:21:40 2021 GMT SHA256 Fingerprint=73:0C:1B:DC:D8:5F:57:CE:5D:C0:BB:A7:33:E5:F1:BA:5A:92:5B:2A:77:1D:64:0A:26:F7:A4:54:22:4D:AD:3B -BEGIN CERTIFICATE- MIIEZTCCA02gAwIBAgIQQAF1BIMUpMghjISpDBbN3zANBgkqhkiG9w0BAQsFADA/ MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT DkRTVCBSb290IENBIFgzMB4XDTIwMTAwNzE5MjE0MFoXDTIxMDkyOTE5MjE0MFow MjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxCzAJBgNVBAMT AlIzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuwIVKMz2oJTTDxLs jVWSw/iC8ZmmekKIp10mqrUrucVMsa+Oa/l1yKPXD0eUFFU1V4yeqKI5GfWCPEKp Tm71O8Mu243AsFzzWTjn7c9p8FoLG77AlCQlh/o3cbMT5xys4Zvv2+Q7RVJFlqnB U840yFLuta7tj95gcOKlVKu2bQ6XpUA0ayvTvGbrZjR8+muLj1cpmfgwF126cm/7 gcWt0oZYPRfH5wm78Sv3htzB2nFd1EbjzK0lwYi8YGd1ZrPxGPeiXOZT/zqItkel /xMY6pgJdz+dU/nPAeX1pnAXFK9jpP+Zs5Od3FOnBv5IhR2haa4ldbsTzFID9e1R oYvbFQIDAQABo4IBaDCCAWQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E BAMCAYYwSwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5p ZGVudHJ1c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTE p7Gkeyxx+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEE AYLfEwEBATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2Vu Y3J5cHQub3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0 LmNvbS9EU1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYf r52LFMLGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0B AQsFAAOCAQEA2UzgyfWEiDcx27sT4rP8i2tiEmxYt0l+PAK3qB8oYevO4C5z70kH ejWEHx2taPDY/laBL21/WKZuNTYQHHPD5b1tXgHXbnL7KqC401dk5VvCadTQsvd8 S8MXjohyc9z9/G2948kLjmE6Flh9dDYrVYA9x2O+hEPGOaEOa1eePynBgPayvUfL qjBstzLhWVQLGAkXXmNs+5ZnPBxzDJOLxhF2JIbeQAcH5H0tZrUlo5ZYyOqA7s9p O5b85o3AM/OJ+CktFBQtfvBhcJVd9wvlwPsk+uyOy2HI7mNxKKgsBTt375teA2Tw UdHkhVNcsAKX1H7GNNLOEADksd86wuoXvg== -END CERTIFICATE- The EE (depth 0 server) certificate is not expired, and yet somehow the server is building a chain with a fresh leaf cert, and a rather stale issuer CA. It verifies via the DANE implementation in OpenSSL, because its "2 1 1" record with a fresh RRSIG specifies the R3 CA as trusted, and its expiration date is not in scope since it was signed by an entity outside the effective trust chain. Validation would fail for the same chain with WebPKI, unless there's a new improved R3 in the trust store (not just the roots). My DANE survey scan engine checks trust-anchor cert expiration date, even when an intermediate CA, mostly because the implementation is done that way, but I can retroactively justify it because it makes sense to be more strict in tools that look for potential issues. Implementations other than OpenSSL might similarly reject such a suboptimal chain. -- Viktor.
Re: SSL_CTX_set_verify uses the "wrong" certificate chain (cross signed certificate )
On Sat, Oct 02, 2021 at 05:24:26PM +0200, Alex Robuchon wrote: > The project has a callback function registered with SSL_CTX_set_verify > and failed to verify DST Root CA X3 since it expired. That happens when either: * The configured trust store (perhaps not the default system trust store) does not contain the ISRG root CA certificate * The version of OpenSSL used (perhaps indirectly via some library that is linked with an older OpenSSL) is 1.0.x rather than 1.1.0 or later. > From what I understood about the let's encrypt certificate chain, R3 is > cross signed and two chained could be built: > >- leaf <- R3 <- ISRG Root X1 <- DST Root CA X3 (self-signed) >- leaf <- R3 <- ISRG Root X1 (self-signed) Yes. To make things even more complex, a few sites also have an older version of R3 that is directly signed by the DST root: - leaf <- R3 <- DST Root CA X3 (self-signed) but that's far from common at this point. > The servers by default return the first chain but from what I > understand depending on the openssl version/flags it should use the > second path if ISRG Root X1 is in the store Yes, see above. > My config : > openssl version : OpenSSL 1.1.1f 31 Mar 2020 Are you sure there are no other versions of OpenSSL also installed on the system, and/or no other trust stores that the application in question might be using instead of the default system store? An "strace" of the process should show which shared objects it is loading, and which cert store files it is opening... Best to not post the complete strace output here, it may contain sensitive data. Try to interpret it on your end and post your findings. > ISRG Root X1 self signed is in my cert store. This presumes a *singular* "trust store", but the application could easily be looking elsewhere. > So from what I understand, trusted first is default in this version of > openssl and the second path should be taken. Yes, per the pre-requisite conditions. > For the record s_client can valide the second path on my machine : > $ echo | openssl s_client -connect retouche-pro.ch:443 -name retouche-pro.ch > -servername retouche-pro.ch > CONNECTED(0003) > depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1 > verify return:1 > depth=1 C = US, O = Let's Encrypt, CN = R3 > verify return:1 > depth=0 CN = retouche-pro.ch > verify return:1 As expected for 1.1.1f and a trust store that contains the ISRG X1 root. > So I suppose the problem relies on the use of openssl in the ruby > libs. Are the ruby libraries linked with OpenSSL 1.1.1? Are they overriding the default system trust store? > However what I'm a bit surprised with is the fact that > SSL_CTX_set_verify is called with the "wrong" certificate chain. I think you mean the callback specified via that function is called with unexpected chain elements, not the function itself... > The documentation says it's going to be called for each certificate in > the chain but do not specify if it's the chain specified by the server > or the one built by openssl with trusted first algorithm. Except when various earlier errors take place during chain construction, those callbacks take place as part of signature verification on the already constructed chain, so the callback normally sees the "trusted" chain, not the server provided certificate "heap" (which may not be linearly ordered). > Is it normal to have the callback defined in SSL_CTX_set_verify to be > called with the wrong chain ? Or do you think something is not configured > correctly on these gems ? See above, the callbacks report the constructed chain, except when some error happens during chain construction. -- Viktor.
Re: openssl 1.0 vs 1.1 s_client verify CA cert expiration
> On 30 Sep 2021, at 3:34 pm, nate wrote: > >> $ openssl s_client -showcerts \ >>-connect bad_server_name:443 \ >>-servername bad_server_name 2>/dev/null | >>openssl crl2pkcs7 -nocrl -certfile /dev/stdin | >>openssl pkcs7 -print_certs -noout -text | >>egrep 'not(Before|After)' >> or write the errors to a separate file. > > > That almost worked.. but because the first openssl command > never completes the other commands just wait.. > > I poked around and found that sending Q to the command gets it > to exit so I came up with this: > > echo "Q" | [...] True, I forgot that I usually write: $ sleep 2 | openssl s_client ... which generally gives s_client enough time to complete the handshake, and then it exits when it sees EOF on stdin. The "Q" is perhaps cleaner. -- Viktor.
Re: openssl 1.0 vs 1.1 s_client verify CA cert expiration
On Thu, Sep 30, 2021 at 11:26:14AM -0700, nate wrote: > > This is *not* the correct way to see all the expiration dates in the > > chain. It will show only the leaf certificate dates. The right > > incantation is: > > > > $ openssl s_client -connect bad_server_name:443 -servername > > bad_server_name | > > openssl crl2pkcs7 -nocrl -certfile /dev/stdin | > > openssl pkcs7 -print_certs -noout -text | > > egrep 'not(Before|After)' > > At least in this case the command you supplied appears to provide less > information: > > (OpenSSL 1.0.2g) > depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3 > verify error:num=10:certificate has expired > notAfter=Sep 30 14:01:15 2021 GMT Ah, you also need to add "-showcerts" to s_client and best to separate stdout and stderr in order to avoid confusion due to error text leaking through, sender stderr to /dev/null: $ openssl s_client -showcerts \ -connect bad_server_name:443 \ -servername bad_server_name 2>/dev/null | openssl crl2pkcs7 -nocrl -certfile /dev/stdin | openssl pkcs7 -print_certs -noout -text | egrep 'not(Before|After)' or write the errors to a separate file. > (OpenSSL 1.0.2g with -trusted_first option) > depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1 > verify return:1 > depth=1 C = US, O = Let's Encrypt, CN = R3 > verify return:1 > depth=0 CN = bad_server_name > verify return:1 Good. > (OpenSSL 1.1.1f) > depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1 > verify return:1 > depth=1 C = US, O = Let's Encrypt, CN = R3 > verify return:1 > depth=0 CN = bad_server_name > verify return:1 Ditto. > Is there a command sequence that could get openssl to show all dates in > the tree whether it is being served by the server or checked in the > local trusted store? The "crl2pkcs7 -nocrl -certfile /dev/stdin" command piped to "pkcs7 -print_certs -text" is how to see the full chain. > I assume your command is intended to do that, but > it doesn't for me. I neglected to suggest "-showcerts". -- Viktor.
Re: openssl 1.0 vs 1.1 s_client verify CA cert expiration
On Thu, Sep 30, 2021 at 09:43:54AM -0700, nate wrote: > If I run this on OpenSSL 1.0.2g (Ubuntu 16.04) > > openssl s_client -connect bad_server_name:443 -servername bad_server_name > > I get at the end a clear: Verify return code: 10 (certificate has expired) This is because OpenSSL 1.0.2 looks at the peer's certificate chain before looking in the trust store. > If I run on the same OpenSSL: > > openssl s_client -connect bad_server_name:443 -servername bad_server_name | > openssl x509 -noout -dates This is *not* the correct way to see all the expiration dates in the chain. It will show only the leaf certificate dates. The right incantation is: $ openssl s_client -connect bad_server_name:443 -servername bad_server_name | openssl crl2pkcs7 -nocrl -certfile /dev/stdin | openssl pkcs7 -print_certs -noout -text | egrep 'not(Before|After)' > If I try the same on OpenSSL 1.1.1f (Ubuntu 20.04), I get only the > server cert > not the CA cert dates: > notBefore=Aug 31 17:59:09 2021 GMT > notAfter=Nov 29 17:59:08 2021 GMT Expected behaviour, you've only asked for the EE cert details. > Also on the first command there is no error saying the cert is expired > on OpenSSL 1.1.1f OpenSSL 1.1.1 looks for issuer certificates first in the trust store and only then in the peer chain. > additional differences it seems 1.1.1f defaults to a verify depth of 2 > and 1.0.2g goes at least > to 3 (perhaps more). Expected, because it finds the ISRG root in the trust store, and so ignores the cross-cert in the peer's chain. Another potential issue (not in this case) is that the Let's Encrypt R3 intermediate issuing CA certificate (same subject DN and public key) is available in two different forms: * One issued by ISRG, still valid * Another issued by DST, expired yesterday. Correctly configured systems that use the Let's Encrypt "full_chain.pem" file are using the ISRG version, and should not have any issues, provided the client system is using OpenSSL 1.1.1 and has the ISRG root CA Servers that update only the Let's encrypt "cert.pem" file and provide the rest of the chain independently, or somehow otherwise manage to be stuck with the DST-signed "R3" now have certificate chains that will fail to validate. -- Viktor.
Re: openssl(1) 3.0 crash
On Thu, Sep 30, 2021 at 02:48:39PM +0200, Steffen Nurpmeso wrote: > Thanks for fixing this so fast. > > ... > |You should open an issue on Github. The immediate cause is: > ... > > I finally (re)created a github account to cause less burden the next > trivial time. But i do not understand a jingle word of what you both > talk about in the issues you referenced. No worries, It appears that in posts upthread I misunderstood the intent of the new code in 3.0.0. The "openssl { | }" commands are not after all deprecated in 3.0.0, it was just that the pointer to their deprecation status was not initialised to NULL. So the fix is a one-liner to zero out the structure `f`, ensuring a NULL deprecation status. -- Viktor
Re: openssl(1) 3.0 crash
On Wed, Sep 29, 2021 at 05:14:45PM -0400, Viktor Dukhovni wrote: > A better fix, that emits the intended deprecation warning would be: > > --- a/apps/openssl.c > +++ b/apps/openssl.c > [...] Opened as pull request https://github.com/openssl/openssl/pull/16714 addressing issue: https://github.com/openssl/openssl/issues/16713 -- Viktor.
Re: openssl(1) 3.0 crash
On Wed, Sep 29, 2021 at 04:59:51PM -0400, Viktor Dukhovni wrote: >400 if (fp == NULL) { >401 if (EVP_get_digestbyname(argv[0])) { >402 f.type = FT_md; >403 f.func = dgst_main; >404 fp = >405 } else if (EVP_get_cipherbyname(argv[0])) { >406 f.type = FT_cipher; >407 f.func = enc_main; >408 fp = >409 } >410 } > > The code is missing "f.deprecated_alternative = NULL" between lines > 409 and 410, or else after each of 403 and 407. A better fix, that emits the intended deprecation warning would be: --- a/apps/openssl.c +++ b/apps/openssl.c @@ -392,6 +392,7 @@ int help_main(int argc, char **argv) static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) { FUNCTION f, *fp; +static char alt_buf[256]; if (argc <= 0 || argv[0] == NULL) return 0; @@ -401,12 +402,16 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) if (EVP_get_digestbyname(argv[0])) { f.type = FT_md; f.func = dgst_main; +(void) BIO_snprintf(alt_buf, sizeof(alt_buf), "dgst -%s", argv[0]); fp = } else if (EVP_get_cipherbyname(argv[0])) { f.type = FT_cipher; f.func = enc_main; +(void) BIO_snprintf(alt_buf, sizeof(alt_buf), "enc -%s", argv[0]); fp = } +f.deprecated_alternative = alt_buf; +f.deprecated_version = "3.0.0"; } if (fp != NULL) { if (fp->deprecated_alternative != NULL) -- Viktor.
Re: openssl(1) 3.0 crash
On Wed, Sep 29, 2021 at 10:30:29PM +0200, Steffen Nurpmeso wrote: > I first thought it was musl related but the AlpineLinux bug report > turned out to be wrong, i can easily reproduce it anywhere, it is > just that the according script only runs there: > > #?0|kent:$ export > LD_LIBRARY_PATH=~/usr-kent-crux-linux-x86_64/opt/.ossl3/lib64/ > #?0|kent:$ ~/usr-kent-crux-linux-x86_64/opt/.ossl3/bin/openssl bla > Invalid command 'bla'; type "help" for a list. > #?1|kent:$ ~/usr-kent-crux-linux-x86_64/opt/.ossl3/bin/openssl chacha20 > Segmentation fault > #?139|kent:$ You should open an issue on Github. The immediate cause is: 46 static void warn_deprecated(const FUNCTION *fp) 47 { 48 if (fp->deprecated_version != NULL) -> 49 BIO_printf(bio_err, "The command %s was deprecated in version %s.", 50 fp->name, fp->deprecated_version); ... but in the case of the "chacha20" command, fp->deprecated_version was not initialised: $10 = { type = FT_cipher name = 0x7ffeefbff47a "chacha20" func = 0x000100021d30 (openssl`enc_main at enc.c:105) help = 0x7ffeefbff1b0 deprecated_alternative = 0x7ffeefbff0b0 "" deprecated_version = 0xef60232fcf210011 "" } and so printing the version of OpenSSL in which it was deprecated crashes. The caller is at fault: 392 static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) 393 { 394 FUNCTION f, *fp; 395 396 if (argc <= 0 || argv[0] == NULL) 397 return 0; 398 f.name = argv[0]; 399 fp = lh_FUNCTION_retrieve(prog, ); 400 if (fp == NULL) { 401 if (EVP_get_digestbyname(argv[0])) { 402 f.type = FT_md; 403 f.func = dgst_main; 404 fp = 405 } else if (EVP_get_cipherbyname(argv[0])) { 406 f.type = FT_cipher; 407 f.func = enc_main; 408 fp = 409 } 410 } 411 if (fp != NULL) { 412 if (fp->deprecated_alternative != NULL) 413 warn_deprecated(fp); 414 return fp->func(argc, argv); 415 } The code is missing "f.deprecated_alternative = NULL" between lines 409 and 410, or else after each of 403 and 407. -- Viktor.
Re: OpenSSL SSL_CTX_set_default_verify_paths Slow
> On 27 Sep 2021, at 11:24 am, Jay Foster wrote: > > I don't think so. The file system is a UBIFS on nand flash, and it works > with 1.0.2 and 1.1.1. Even 1.1.1 is a *little* bit slower than 1.0.2, but > nowhere near as much slower as 3.0.0. > > It looks like the OpenSSL library is reading the cert.pem file in 4KB blocks > at a time and doing some processing on the data read. It appears that this > processing is what is taking longer. OpenSSL 3.0.0 has a new OSSL_DECODER API, it may still need some performance tuning? For example, in Postfix + OpenSSL 3.0.0 I'm decoding the compiled-in DER DH group via: +static void load_builtin(void) +{ +EVP_PKEY *tmp = 0; +OSSL_DECODER_CTX *d; +const unsigned char *endp = builtin_der; +size_t dlen = sizeof(builtin_der); + +d = OSSL_DECODER_CTX_new_for_pkey(, "DER", NULL, "DH", + OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, + NULL, NULL); +/* Check decode succeeds and consumes all data (final dlen == 0) */ +if (d && OSSL_DECODER_from_data(d, , ) && tmp && !dlen) { + dhp = tmp; +} else { + EVP_PKEY_free(tmp); + msg_warn("error loading compiled-in DH parameters"); + tls_print_errors(); +} +OSSL_DECODER_CTX_free(d); +} IIRC the loading of certificates now uses this API. There was perhaps also some work on new X509_STORE infrastructure. Performance issues in the new code are not implausible, and I hope can be addressed in upcoming releases. -- Viktor.
Re: Will TLSv1.3 always send session ticket?
On Thu, Sep 16, 2021 at 09:49:31AM -0700, Benjamin Kaduk via openssl-users wrote: > I'd be interested in hearing your thoughts about what an API/config would look > like to enable the delayed-send behavior. A simple boolean SSL_CONF_CMD called something like: -ticket_delay, or -ticket_data_prepend would cause the ticket generation to be deferred until the first application data write from server to client. The API would be either a direct call to set the boolean, or an indirect action via the SSL_CONF layer. This would require a new bit to set the policy in the SSL_CTX that would be inherited by any derived SSL handles. The first data transmission would inspect the desired ticket count computed during the handshake, and send that many tickets, resetting the count to zero. The current immediate transmission of tickets would merely squirrel away the number of tickets to send with the first batch of data. -- Viktor.
Re: Getting SSL_SESSION remaining lifetime
On Thu, Sep 16, 2021 at 06:50:40PM +0200, Hubert Kario wrote: > On Thursday, 16 September 2021 17:59:48 CEST, Viktor Dukhovni wrote: > > The Internet does not solely consist of browser traffic from portable > > devices at wifi hotspots to taboo web sites. > > taboo web sites are not the only reason to expect privacy... Indeed, but there are also applications in which client "privacy" is both unavailable and undesirable. One size does not fit all. -- Viktor.
Re: Will TLSv1.3 always send session ticket?
On Thu, Sep 16, 2021 at 09:30:18AM -0700, Benjamin Kaduk via openssl-users wrote: > On Thu, Sep 16, 2021 at 12:20:05PM -0400, Viktor Dukhovni wrote: > > > > I don't recall whether OpenSSL makes any effort to or supports deferring > > the transmission of session tickets until just before the first > > application data transmission from server to client (or else perhaps > > just before responding to a received close-notify with a reciprocal > > close-notify) > > It's not the default behavior, but is supported: you can configure the > SSL/SSL_CTX to send zero tickets by default and then manually call > SSL_new_session_ticket(), which defers the transmission until there is another > write or explicit SSL_do_handshake() call. So nothing built-in... What I had in mind was a built-in behaviour of the library to delay session ticket transmission until there's a first opportunity to send some application data, which the client application can be reasonably expected to read at that point. If this is left entirely to applications, many of the less sophisticated ones might not know to consider the issue. In my SMTP use-cases, after STARTTLS, the client is expected to send a short "EHLO" command, and then turn around and read a server response, so deadlock would require a very small TCP window on the server side, and/or an unreasonably large (many kilobytes) client EHLO name. So Postfix does not take any application-layer steps to postpone session ticket transmission. I also would not to send session tickets without an indication that the client did not present a sufficiently fresh ticket, so handling session ticket generation in the application logic would become even more complex... -- Viktor.
Re: Will TLSv1.3 always send session ticket?
On Thu, Sep 16, 2021 at 10:05:44AM +0100, Matt Caswell wrote: > No. Unless you configure the server otherwise OpenSSL will always send > session ticket(s) in TLSv1.3. It may be worth mentioning a discussion from some time back on the TLSWG list started by David Benjamin that notes that in TLS 1.3 it is not always opportune for the server to send post-handshake session resumption tickets unless it is also sending some application data. If the application protocol in question has the client sending first and delivering a large request to the server before attempting to read a response, an "unsolicited" transmission of session tickets from server to client may cause an application protocol deadlock if the client's TCP window is not large enough to accommodate the session tickets withour any client-side reads. This situation can with some justification be argued to be a defect in the TLS 1.3 protocol. I don't recall whether OpenSSL makes any effort to or supports deferring the transmission of session tickets until just before the first application data transmission from server to client (or else perhaps just before responding to a received close-notify with a reciprocal close-notify) -- Viktor.
Re: Getting SSL_SESSION remaining lifetime
On Thu, Sep 16, 2021 at 04:11:49PM +0200, Hubert Kario wrote: > On Thursday, 16 September 2021 04:41:44 CEST, Jaya Muthiah wrote: > > > > I am trying to get the remaining lifetime of the ticket so that > > server can decide to renew ticket or not > > TLS 1.3 tickets are single use. If the ticket was used by a client, > and you expect it to make a connection in the future, server needs to > send a new one. This is wrong both in terms of specification and the extant OpenSSL implementation. The Postfix SMTP server arranges to accept multi-use tickets without reissuing replacement tickets when the original ticket is still good for reuse. Ticket reuse is well suited to the MTA-to-MTA use-case where "privacy" is not only a concern but in fact undesirable. MTAs often reject traffic from senders with no PTR records, generic PTR records, poor IP reputation, The Internet does not solely consist of browser traffic from portable devices at wifi hotspots to taboo web sites. -- Viktor.
Re: Getting SSL_SESSION remaining lifetime
On Thu, Sep 16, 2021 at 08:11:44AM +0530, Jaya Muthiah wrote: > I am trying to get the remaining lifetime of the ticket so that server can > decide to renew ticket or not In Postfix, I rotate ticket keys every hour, and sessions are valid for two hours. For the first hour when they were issued by the current ticket the ticket is accepted without forcing a new ticket to be generated. Durign the second hour when accepting tickets signed by the previous key, a fresh ticket is generated. I don't rely on OpenSSL to tell me the ticket age, it is implied by the key id. Since ticket keys should be rotated anyway, something like that might also work for you. What I haven't yet built is a mechanism to rotate keys consistely across multiple machines in a load-balancer pool. That would be generally useful. -- Viktor.
Re: OpenSSL session reuse does not work with TLS_client_method()
On Wed, Sep 15, 2021 at 05:26:51PM +0530, Jaya Muthiah wrote: > I am trying to reuse SSL_SESSION as below, it works fine when I use > TLSv1_2_client_method() to create context. However, it does not work > when I use TLS_client_method(). > [...] > if (SSL_connect(ssl) != 1) { return -1; } > int reused = SSL_session_reused(ssl); > ssl_session = SSL_get1_session(ssl); // for future connections That's because with TLS_client_method() you end up negotiating TLS 1.3, and with TLS 1.3 session tickets are sent by servers *after* the completion of the handshake. A TLS 1.3 session saved manually, immediately at the completion of the handshake will have no session tickets, and will not be able to perform resumption. The robust way to save the session state for resumption is to implement the session callbacks. For example, in Postfix, you'll find: SSL_CTX_set_session_cache_mode(client_ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE | SSL_SESS_CACHE_NO_AUTO_CLEAR); SSL_CTX_sess_set_new_cb(client_ctx, new_client_session_cb); static int new_client_session_cb(SSL *ssl, SSL_SESSION *session) { ... /* * The cache name (if caching is enabled in tlsmgr(8)) and the cache ID * string for this session are stored in the TLScontext. It cannot be * null at this point. */ if ((TLScontext = SSL_get_ex_data(ssl, TLScontext_index)) == 0) msg_panic("%s: null TLScontext in new session callback", myname); ... } -- Viktor. [ We all miss the little details sometimes, but I'd have expected Matt to not miss this one... ]