sassoftware / relic

Relic is a service and a tool for adding digital signatures to operating system packages for Linux and Windows
Apache License 2.0
151 stars 41 forks source link

certificate does not match key in token #12

Closed antoinedeschenes closed 2 years ago

antoinedeschenes commented 2 years ago

I'm having a "certificate does not match key in token" issue where the exponent is showing up as 65537 in relic token contents and the certificate also shows 65537.

I dumped the objects in the SameKey function, and key.E is 16777472, while cert.Leaf.PublicKey.E is 65537, triggering an error (both N are identical and the token works with other apps)

Using a pkcs11 token with an RSA key.

https://github.com/sassoftware/relic/blob/ffc26ac9491b20a12031f20eff211adc2df20350/lib/certloader/certloader.go#L220

Extra info:

65537 seems to be a reserved/default value https://www.cryptsoft.com/pkcs11doc/v220/group__SEC__12__1__4__PKCS____1__RSA__KEY__PAIR__GENERATION.html

16777472 is 65537 when using the wrong endianness. So there might be an issue there.

I could try to compare with another token in my possession that was working correctly previously when using a different CA.

mtharp commented 2 years ago

Could you please provide the raw exponent bytes that toRsaKey gets, including any padding?

antoinedeschenes commented 2 years ago

Hi @mtharp,

Here are the results:

toRsaKey exponent 00010001
toRsaKey e 1000100

Given these changes used to print the two variables:

diff --git a/token/p11token/rsa.go b/token/p11token/rsa.go
index b54c652..c7ce6b8 100644
--- a/token/p11token/rsa.go
+++ b/token/p11token/rsa.go
@@ -20,6 +20,7 @@ import (
        "crypto"
        "crypto/rsa"
        "errors"
+       "fmt"
        "math/big"

        "github.com/miekg/pkcs11"
@@ -31,11 +32,13 @@ import (
 func (key *Key) toRsaKey() (crypto.PublicKey, error) {
        modulus := key.token.getAttribute(key.pub, pkcs11.CKA_MODULUS)
        exponent := key.token.getAttribute(key.pub, pkcs11.CKA_PUBLIC_EXPONENT)
+       fmt.Printf("toRsaKey exponent %x\n", exponent)
        if len(modulus) == 0 || len(exponent) == 0 {
                return nil, errors.New("Unable to retrieve RSA public key")
        }
        n := new(big.Int).SetBytes([]byte(modulus))
        e := int(attrToInt(exponent))
+       fmt.Printf("toRsaKey e %x\n", e)
        return &rsa.PublicKey{N: n, E: e}, nil
 }

Replacing attrToInt has worked for us: https://github.com/sassoftware/relic/pull/14

mtharp commented 2 years ago

Thanks for the report, CKA_PUBLIC_EXPONENT is indeed meant to be parsed as a big-endian bigint. I've expanded on the change a bit to make the things that are supposed to be ulongs more correct, and checked to make sure there aren't any other incorrect uses of attrToInt.