Skip to content
This repository has been archived by the owner on Aug 19, 2022. It is now read-only.

set a random certificate subject #100

Merged
merged 2 commits into from
Nov 23, 2021
Merged

set a random certificate subject #100

merged 2 commits into from
Nov 23, 2021

Conversation

marten-seemann
Copy link
Collaborator

Fixes #97. @peterargue, can you confirm that this fixes the problem with the Java implementation?

According to RFC3280, the issuer field must not be empty.

@peterargue
Copy link

Thanks for picking this up so quickly @marten-seemann.

I believe there are a few other changes required to be compliant with that RFC. From a quick review it will also need

the general requirement (https://datatracker.ietf.org/doc/html/rfc3280#section-4.1.2):

Every TBSCertificate contains the names of the subject and issuer, a public key associated with the subject, a validity period, a version number, and a serial number.

I may not have captured everything, and there may be some additional fields required for a self-signed cert since it's also a CA.

@marten-seemann
Copy link
Collaborator Author

Subject: this should include a DN that matches the issuer since it's self-signed.

Not sure what to do here, we're using tmpl for both template and parent in x509.CreateCertificate. Can you suggest a fix?

Version: this should be v3 (0x2) to support adding extensions https://datatracker.ietf.org/doc/html/rfc3280#section-4.1.2.9

I'm pretty sure we don't need to set this manually, at least parsing a certificate generated with keyToCertificate yields a cert that already has a 3 set here.

@peterargue
Copy link

You're right, version is populated by default: https://github.com/golang/go/blob/master/src/crypto/x509/x509.go#L1551-L1560

Looks like you just need to pass the pkix.Name as Subject (instead of issuer) and CreateCertificate will populate the issuer field automatically.

The other fields like KeyUsage/ExtKeyUsage/BasicConstraintsValid/IsCA are probably not strictly required. cURL doesn't require them anyway. Some clients may want a CN in the subject field that matches the hostname.

cURL specifically complains about the NotBefore containing a zero time. That may be a client implementation issue, but a start time with a real timestamp might help.
e.g.

NotBefore:    time.Now().Add(-24 * time.Hour),

crypto.go Outdated Show resolved Hide resolved
@marten-seemann
Copy link
Collaborator Author

cURL specifically complains about the NotBefore containing a zero time. That may be a client implementation issue, but a start time with a real timestamp might help.

That's weird. Probably not worth to debug this further, we can just set the time here.

@marten-seemann
Copy link
Collaborator Author

@peterargue Can you confirm if this works asap? We might be able to include this fix in the go-libp2p v0.16.0 release then.

@marten-seemann marten-seemann changed the title set a random certificate issuer set a random certificate subject Nov 22, 2021
Copy link

@peterargue peterargue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I've reached out to our community member that ran into this issue to test, but from code inspection of the java library, this should parse correctly.

crypto.go Outdated
if err != nil {
return nil, err
}
issuerSN, err := rand.Int(rand.Reader, bigNum)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: subjectSN

Copy link
Contributor

@vyzo vyzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so why does it have to be random? We could just have the peer ID or a constant string like libp2p.

@marten-seemann
Copy link
Collaborator Author

It needs to be unique, so a constant string doesn’t work. Random because that will prevent people from using this value, which might break later when we see the need to change it.

@peterargue
Copy link

Random because that will prevent people from using this value, which might break later when we see the need to change it.

what's the concern here? that implementers might use the internal value you set within their logic and that could break if you decide to change the cert format?

You could get around that by accepting a cert template. then implementers can define their own settings and the library is only responsible for adding the extension. You could also introduce a version to the signedKey struct if you want a way to manage compatibility between releases.

@vyzo
Copy link
Contributor

vyzo commented Nov 22, 2021

so why not use the peer ID?

@marten-seemann
Copy link
Collaborator Author

so why not use the peer ID?

what's the concern here? that implementers might use the internal value you set within their logic and that could break if you decide to change the cert format?

Exactly. It's been a painful lesson learned from protocol design: If you're exposing something, someone will come to rely on this. That's why the IETF has introduced the concept of GREASE in recent years.

You could get around that by accepting a cert template. then implementers can define their own settings and the library is only responsible for adding the extension. You could also introduce a version to the signedKey struct if you want a way to manage compatibility between releases.

That seems out of scope for this PR.

@marten-seemann marten-seemann merged commit efdc0b4 into master Nov 23, 2021
bors bot added a commit to onflow/flow-go that referenced this pull request Nov 30, 2021
1694: Update libp2p-tls to fix issue with secured gRPC certificate r=peterargue a=peterargue

Depends on #1692, which updates the min go version to 1.16.

Updates required to pull in this change: libp2p/go-libp2p-tls#100

The `libp2p/go-libp2p-tls` PR updates the certificate generated by the `NewIdentity` method to include subject and issuer fields, making it compliant with the x509 Certificate standard ([RFC3280](https://datatracker.ietf.org/doc/html/rfc3280#section-4.1.2)).

This involves updating various other libp2p libraries, which now require go version 1.16.

Co-authored-by: Peter Argue <[email protected]>
@aschmahmann aschmahmann mentioned this pull request Dec 1, 2021
80 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add issuer DN field to generated cert
3 participants