-
-
Notifications
You must be signed in to change notification settings - Fork 611
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Identifiers to Authorization & Order structs #7961
base: main
Are you sure you want to change the base?
Conversation
Add `identifier` fields, which will soon replace the `dnsName` fields, to: - `corepb.Authorization` - `corepb.Order` - `rapb.NewOrderRequest` - `sapb.CountFQDNSetsRequest` - `sapb.CountInvalidAuthorizationsRequest` - `sapb.FQDNSetExistsRequest` - `sapb.GetAuthorizationsRequest` - `sapb.GetOrderForNamesRequest` - `sapb.GetValidAuthorizationsRequest` - `sapb.NewOrderRequest` Populate these `identifier` fields in every function that creates instances of these structs. Preferentially use these `identifier` fields in every function that uses these structs - but when crossing component boundaries, don't assume they'll be present, for deployability's sake. Part of #7311
…within structs only
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reviewed everything except for ra_test.go and wfe.go, but thought it best to send these comments ASAP. I think I will have further thoughts on the exact names and APIs you've created inside identifier.go, but what you have there is certainly good enough to be getting on with for now.
core/proto/core.proto
Outdated
string dnsName = 2; | ||
string status = 4; | ||
google.protobuf.Timestamp expires = 9; | ||
repeated core.Challenge challenges = 6; | ||
core.Identifier identifier = 10; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interestingly I don't think this needs the core.
prefix, because we're in core
right here. See for example the use of unqualified ProblemDetails
on line 123. I'm not sure why we used core.Challenge
on the line above this...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: here and throughout, please put the new identifier(s)
field immediately adjacent to the existing dnsName(s)
field. This is because the fields (especially in sections prefixed with // Fields specified by RFC 8555
) are listed in the same order as the fields are in the RFC.
// TODO(#7311): Process IP address identifiers appropriately, and | ||
// consistently with how we stringify IPs elsewhere. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this TODO is unnecessary: the .Value
field of an ACMEIdentifier is already a string, so no stringification should need to happen inside this function.
@@ -340,30 +340,45 @@ func TestRetryBackoff(t *testing.T) { | |||
|
|||
} | |||
|
|||
func TestHashNames(t *testing.T) { | |||
func TestHashIdentifiers(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a test case for all identfier.NewIP()
, and one or more test cases for a mixes of IP and DNS identifiers in various orders. Might be a good time to turn this into a table-based test, too.
@@ -310,16 +311,16 @@ func (c *certChecker) checkValidations(ctx context.Context, cert core.Certificat | |||
|
|||
// We may get multiple authorizations for the same name, but that's okay. | |||
// Any authorization for a given name is sufficient. | |||
nameToAuthz := make(map[string]*corepb.Authorization) | |||
identToAuthz := make(map[string]*corepb.Authorization) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Identifiers are comparable: they only have two fields, both of which are concrete strings. You should be able to use them directly as map keys, rather than collapsing them into just their values.
@@ -40,7 +41,7 @@ func TestValidAuthzExpires(t *testing.T) { | |||
|
|||
// The authz should be valid and for the correct identifier | |||
test.AssertEquals(t, authzOb.Status, "valid") | |||
test.AssertEquals(t, authzOb.Identifier.Value, domains[0]) | |||
test.AssertEquals(t, authzOb.Identifier.Value, idents[0].Value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check that the identifier type has round-tripped correctly.
@@ -89,7 +91,7 @@ func delHTTP01Response(token string) error { | |||
return nil | |||
} | |||
|
|||
func makeClientAndOrder(c *client, csrKey *ecdsa.PrivateKey, domains []string, cn bool, certToReplace *x509.Certificate) (*client, *acme.Order, error) { | |||
func makeClientAndOrder(c *client, csrKey *ecdsa.PrivateKey, idents []identifier.ACMEIdentifier, cn bool, certToReplace *x509.Certificate) (*client, *acme.Order, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should be acme.Identifiers, not identifier.ACMEIdentifier, since this is client-side code not server-side code. Same with the other functions you've touched in this file.
// TODO(#7311): Extend this to support IP address identifiers. | ||
names := make([]string, len(idents)) | ||
for i, ident := range idents { | ||
names[i] = ident.Value | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can do this right now:
// TODO(#7311): Extend this to support IP address identifiers. | |
names := make([]string, len(idents)) | |
for i, ident := range idents { | |
names[i] = ident.Value | |
} | |
names := make([]string, 0) | |
ips := make([]net.IP, 0) | |
for _, ident := range idents { | |
switch ident.Type: | |
case "dns": | |
names = append(names, ident.Value) | |
case "ip": | |
ips = append(ips, ident.Value) | |
default: | |
return nil, fmt.Errorf("unrecognized identifier type %q", ident.Type) | |
} |
for key, ident := range idents { | ||
pbIdents[key] = ident.AsProto() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not quite idiomatic to refer to array indices as "keys", so:
for key, ident := range idents { | |
pbIdents[key] = ident.AsProto() | |
for i, ident := range idents { | |
pbIdents[i] = ident.AsProto() |
@@ -48,6 +75,16 @@ func NewDNS(domain string) ACMEIdentifier { | |||
} | |||
} | |||
|
|||
// SliceNewDNS is a convenience function for creating a slice of ACMEIdentifiers | |||
// with Type "dns" for a given slice of domain names. | |||
func SliceNewDNS(domains []string) []ACMEIdentifier { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you make this
func SliceNewDNS(domains []string) []ACMEIdentifier { | |
func SliceNewDNS(domains ...string) []ACMEIdentifier { |
then everywhere you call it, you can just pass it a bunch of individual strings like identifier.SliceNewDNS("hello", "world")
instead of having to package them into a slice like identifier.SliceNewDNS([]string{"hello", "world"})
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From our convo: actually I think this can be almost entirely replaced by the combination of
- SliceFromProto(idents []ACMEIdentifier, dnsNames []string), for when extracting from the two fields of a proto message;
- SliceFromCert(x509.Certificate); and
- csr.IdentsFromCSR(x509.CertificateRequest), upgraded from csr.NamesFromCSR.
Add
identifier
fields, which will soon replace thednsName
fields, to:corepb.Authorization
corepb.Order
rapb.NewOrderRequest
sapb.CountFQDNSetsRequest
sapb.CountInvalidAuthorizationsRequest
sapb.FQDNSetExistsRequest
sapb.GetAuthorizationsRequest
sapb.GetOrderForNamesRequest
sapb.GetValidAuthorizationsRequest
sapb.NewOrderRequest
Populate these
identifier
fields in every function that creates instances of these structs.Use these
identifier
fields instead ofdnsName
fields (at least preferentially) in every function that uses these structs. When crossing component boundaries, don't assume they'll be present, for deployability's sake.Deployability note: Mismatched
cert-checker
andsa
versions will be incompatible because of a type change in the arguments tosa.SelectAuthzsMatchingIssuance
.Part of #7311