Git Product home page Git Product logo

Comments (8)

jpastuszek avatar jpastuszek commented on July 18, 2024

Looks like I am getting None from $key.ec_key()?.group().curve_name().

from acmed.

breard-r avatar breard-r commented on July 18, 2024

This is very strange. It seems that OpenSSL/LibreSSL is able to create the account's EC key pair but then doesn't recognize it, which makes no sense. I just pushed a patch that displays a more precise error message. Can you build the master branch and then re-run it with the trace log-level please?

from acmed.

jpastuszek avatar jpastuszek commented on July 18, 2024

So I get None from .curve_name() so I added extra debugging and got this:

warn!("id: {:?}, ec_key: {:?}, group: {:?}", $key.id(), $key.ec_key(), $key.ec_key()?.group().curve_name());

Will result in: id: Id(408), ec_key: Ok(EcKey), group: None

If I return KeyType::EcdsaP256 in the None => branch I get this to work OK.

from acmed.

jpastuszek avatar jpastuszek commented on July 18, 2024

So I got it all working with LibreSSL on my PC but on my server with OpenSSL 1.0.2k I am getting this error:

[2019-11-15T17:04:48Z WARN  acmed::certificate] crt-1: Unable to renew the certificate: error:10074065:elliptic curve routines:EC_POINT_get_affine_coordinates_GFp:incompatible objects:ec_lib.c:892:

from acmed.

jpastuszek avatar jpastuszek commented on July 18, 2024

OpenSSL EC_POINT_get_affine_coordinates_GFp can fail if point in not in compact encoding: https://github.com/openssl/openssl/blob/54a0d4ceb28d53f5b00a27fc5ca8ff8f0ddf9036/crypto/ec/ec_lib.c#L838

static ossl_inline int ec_point_is_compat(const EC_POINT *point,
                                          const EC_GROUP *group)
{
    return group->meth == point->meth
           && (group->curve_name == 0
               || point->curve_name == 0
               || group->curve_name == point->curve_name);
}

So if curve_name is not known it will fail like that... so my workaround is causing this and the root cause is that loaded key is not recognised as know curve for some reason.

from acmed.

jpastuszek avatar jpastuszek commented on July 18, 2024

OK, the problem is that you are saving the PKey object and not the EcKey to pem file.
The difference is that PKey does not know which group the EC was from, only all the parameter it needs to know about the final curve:

$ openssl ec -in /tmp/acc/eHh4.priv-key.pem -text
read EC key
Private-Key: (256 bit)
priv:
    00:cc:9d:95:81:68:4b:e1:40:71:a6:b4:cd:27:8c:
    68:4c:38:b1:98:4a:11:8e:5d:c0:b5:b7:9f:f2:75:
    2d:98:e7
pub:
    04:2f:bd:12:f1:c4:96:32:dd:15:f7:00:06:66:56:
    3f:52:cf:b6:ad:34:99:23:52:13:1c:59:a9:5e:53:
    b1:49:af:35:59:1a:68:01:b9:8e:23:b9:31:1c:d7:
    9c:96:3d:ab:c9:e7:dd:47:20:ab:36:86:64:a5:f9:
    74:2f:df:aa:a9
Field Type: prime-field
Prime:
    00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
    00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff
A:
    00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
    00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:fc
B:
    5a:c6:35:d8:aa:3a:93:e7:b3:eb:bd:55:76:98:86:
    bc:65:1d:06:b0:cc:53:b0:f6:3b:ce:3c:3e:27:d2:
    60:4b
Generator (uncompressed):
    04:6b:17:d1:f2:e1:2c:42:47:f8:bc:e6:e5:63:a4:
    40:f2:77:03:7d:81:2d:eb:33:a0:f4:a1:39:45:d8:
    98:c2:96:4f:e3:42:e2:fe:1a:7f:9b:8e:e7:eb:4a:
    7c:0f:9e:16:2b:ce:33:57:6b:31:5e:ce:cb:b6:40:
    68:37:bf:51:f5
Order:
    00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:
    ff:ff:bc:e6:fa:ad:a7:17:9e:84:f3:b9:ca:c2:fc:
    63:25:51
Cofactor:  1 (0x1)
Seed:
    c4:9d:36:08:86:e7:04:93:6a:66:78:e1:13:9d:26:
    b7:81:9f:7e:90
writing EC key
-----BEGIN EC PRIVATE KEY-----
MIIBaAIBAQQgzJ2VgWhL4UBxprTNJ4xoTDixmEoRjl3Atbef8nUtmOeggfowgfcC
AQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA////////////////
MFsEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57Pr
vVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEE
axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54W
K84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8
YyVRAgEBoUQDQgAEL70S8cSWMt0V9wAGZlY/Us+2rTSZI1ITHFmpXlOxSa81WRpo
AbmOI7kxHNeclj2ryefdRyCrNoZkpfl0L9+qqQ==
-----END EC PRIVATE KEY-----

If I generate the key with OpenSSL I get it in the format that has the curve group and point:

openssl ecparam -name prime256v1 -genkey -noout -out my.key.pem
$ openssl ec -in my.key.pem -text
read EC key
Private-Key: (256 bit)
priv:
    00:f1:9e:3d:87:45:6c:90:4b:3a:31:02:d5:dd:2e:
    71:3f:5c:ad:4d:c9:20:f6:14:80:e9:e2:51:8b:da:
    3e:64:9f
pub:
    04:10:30:e4:3b:f4:38:16:a3:52:76:e5:a7:22:a2:
    a5:63:6f:ea:fe:d5:cd:08:6f:f9:9a:06:a3:73:e0:
    aa:9d:f3:59:23:cb:f9:85:ca:3c:92:cc:30:31:17:
    8f:66:0a:e8:92:44:66:06:64:21:b9:19:4c:8c:7c:
    53:54:2d:9d:9d
ASN1 OID: prime256v1
NIST CURVE: P-256
writing EC key
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIPGePYdFbJBLOjEC1d0ucT9crU3JIPYUgOniUYvaPmSfoAoGCCqGSM49
AwEHoUQDQgAEEDDkO/Q4FqNSduWnIqKlY2/q/tXNCG/5mgajc+CqnfNZI8v5hco8
kswwMRePZgrokkRmBmQhuRlMjHxTVC2dnQ==
-----END EC PRIVATE KEY-----

Generated key like this will load fine and acmed will be able to function correctly.

On the side note apparently LibreSSL does not need curve_name to get affine_coordinates while OpenSSL does.

Also with certificate with algorithm = "ecdsa_p256" set even if I generate the account key with OpenSSL I will get this error:

[2019-11-18T14:47:47Z TRACE acmed::certificate] crt-1: Writing file "/etc/acmed/certs/hello2.whatclinic.net_ecdsa-p256.pk.pem"
...
[2019-11-18T14:47:47Z DEBUG acmed::certificate] crt-1: POST: https://acme-staging-v02.api.letsencrypt.org/acme/finalize/11595370/62009620
[2019-11-18T14:47:48Z TRACE acmed::certificate] crt-1: response body: {
      "type": "urn:ietf:params:acme:error:malformed",
      "detail": "Error parsing certificate request: x509: failed to parse ECDSA parameters as named curve",
      "status": 400
    }

The key for certificate also look like this:

read EC key
Private-Key: (256 bit)
priv:
    00:f8:47:da:d5:26:f7:d1:fa:63:33:05:2a:11:9e:
    86:ff:ba:f2:e1:57:56:e6:62:5b:17:dd:cc:aa:d5:
    ff:73:e7
pub:
    04:40:e3:bf:45:0a:4b:de:57:fe:6c:74:d2:d4:46:
    b0:fc:84:c0:45:4c:4e:8e:de:77:11:94:c4:e5:8d:
    2c:80:6a:e6:11:1c:d3:5d:88:1c:ed:07:43:d4:2f:
    de:3e:eb:57:6c:ed:42:b2:b3:e2:07:c5:66:e9:f3:
    74:26:9a:f9:54
Field Type: prime-field
Prime:
    00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
    00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:ff
A:
    00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
    00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
    ff:ff:fc
B:
    5a:c6:35:d8:aa:3a:93:e7:b3:eb:bd:55:76:98:86:
    bc:65:1d:06:b0:cc:53:b0:f6:3b:ce:3c:3e:27:d2:
    60:4b
Generator (uncompressed):
    04:6b:17:d1:f2:e1:2c:42:47:f8:bc:e6:e5:63:a4:
    40:f2:77:03:7d:81:2d:eb:33:a0:f4:a1:39:45:d8:
    98:c2:96:4f:e3:42:e2:fe:1a:7f:9b:8e:e7:eb:4a:
    7c:0f:9e:16:2b:ce:33:57:6b:31:5e:ce:cb:b6:40:
    68:37:bf:51:f5
Order:
    00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:
    ff:ff:bc:e6:fa:ad:a7:17:9e:84:f3:b9:ca:c2:fc:
    63:25:51
Cofactor:  1 (0x1)
Seed:
    c4:9d:36:08:86:e7:04:93:6a:66:78:e1:13:9d:26:
    b7:81:9f:7e:90
writing EC key
-----BEGIN EC PRIVATE KEY-----
MIIBaAIBAQQg+Efa1Sb30fpjMwUqEZ6G/7ry4VdW5mJbF93MqtX/c+eggfowgfcC
AQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA////////////////
MFsEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57Pr
vVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEE
axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54W
K84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8
YyVRAgEBoUQDQgAEQOO/RQpL3lf+bHTS1Eaw/ITARUxOjt53EZTE5Y0sgGrmERzT
XYgc7QdD1C/ePutXbO1CsrPiB8Vm6fN0Jpr5VA==
-----END EC PRIVATE KEY-----

So this looks like same issue but when generating key for the certificate.

from acmed.

breard-r avatar breard-r commented on July 18, 2024

Your last message gave me the key to the solution. Between OpenSSL 1.0 and 1.1 there has been a change in the PEM format generated by the PEM_write_bio_PKCS8PrivateKey function (1.0.2 manual, 1.1.0 manual, look for PEM_write_bio_PKCS8PrivateKey()). As you can see, which is confirmed by your example, 1.0 uses a legacy format (called "traditional") which includes all of the curve's parameters whereas 1.1 only stores the curve's identifier.

Obviously, 1.1 can transparently handles both formats, but 1.0 only accepts the legacy one. You compiled ACMEd against 1.0, this is why it generates every key in the legacy format and cannot handle the newer key you manually generated with a higher version.

Also, this legacy format is obviously the reason why no NID is returned when calling .curve_name() (the curve itself is stored instead of its identifier), hence your first issue. Because there is nothing I can do about it, I think the solution is to explicitly require OpenSSL 1.1 (and maybe an equivalent for LibreSSL).

from acmed.

jpastuszek avatar jpastuszek commented on July 18, 2024

The difference is in defaults of EcGroup between versions as described on:
https://docs.rs/openssl/0.10.25/openssl/ec/struct.EcGroupRef.html#method.set_asn1_flag

So to get this working it should be sufficient to add this line:

group.set_asn1_flag(Asn1Flag::NAMED_CURVE);

Let me try it out and if this works I will send a PR.

from acmed.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.