Commit Graph

41 Commits

Author SHA1 Message Date
Aaron Gable 1d713ed8eb
Ignore IP CNs in CSRs (#8231)
If a finalize CSR contains a SAN which looks like an IP address, don't
actually include that CN in our IssuanceRequest, and don't promote any
other SAN to be the CN either. This is similar to how we ignore the
CSR's CN when it is too long.
2025-06-06 14:57:12 -07:00
James Renken 103ffb03d0
wfe, csr: Add IP address identifier support & integration test (#8187)
Permit all valid identifier types in `wfe.NewOrder` and `csr.VerifyCSR`.

Permit certs with just IP address identifiers to skip
`sa.addIssuedNames`.

Check that URI SANs are empty in `csr.VerifyCSR`, which was previously
missed.

Use a real (Let's Encrypt) IP address range in integration testing, to
let challtestsrv satisfy IP address challenges.

Fixes #8192
Depends on #8154
2025-05-27 13:17:47 -07:00
James Renken b4308df0cc
identifier: Add FromCert & FromCSR; move Normalize from core (#8065)
Part of #7311
2025-03-19 17:03:59 -04:00
James Renken 9f4b18c6ce
identifier: Rename FromDNSNames & AsProto; add ACMEIdentifiers named type (#8070)
Rename `FromDNSNames` to `NewDNSSlice`, since it's exactly `NewDNS`
except for slices.

Rename `AsProto` to use the "To" prefix, since it's the opposite of
"From".

Add a named type `ACMEIdentifiers` so that we can add methods to slices.
We will have a lot of slice handling code coming up, which this will
make more elegant and readable.

Add a comment to explain naming conventions in the `identifier` package.

Part of #7311
Alternative to #8068
2025-03-19 17:03:39 -04:00
James Renken cb94164b54
policy: Add initial Identifier support (#8064)
Change WillingToIssue and WellFormedDomainNames to use Identifiers, and
(for now) reject non-DNS identifiers.

Part of #7311
2025-03-14 11:34:59 -07:00
James Renken 412e959063
Allow CSRs whose CN is longer than acceptable (#7700)
Also rework comments & test names for clarity, add tests for this new CN
handling, and change/remove tests that should indeed no longer fail.

Fixes https://github.com/letsencrypt/boulder/issues/7623
2024-09-10 14:05:32 -04:00
forcedebug b33d28c8bd
Remove repeated words in comments (#7445)
Signed-off-by: forcedebug <forcedebug@outlook.com>
2024-04-23 10:30:33 -04:00
Aaron Gable 78e4e82ffa
Feature cleanup (#7320)
Remove three deprecated feature flags which have been removed from all
production configs:
- StoreLintingCertificateInsteadOfPrecertificate
- LeaseCRLShards
- AllowUnrecognizedFeatures

Deprecate three flags which are set to true in all production configs:
- CAAAfterValidation
- AllowNoCommonName
- SHA256SubjectKeyIdentifier

IN-9879 tracked the removal of these flags.
2024-02-13 17:42:27 -08:00
Samantha d281702c17
PA: Improve wildcard exact blocklist implementation (#7218)
Revamp WillingToIssueWildcards to WillingToIssue. Remove the need for
identifier.ACMEIdentifiers in the WillingToIssue(Wildcards) method.
Previously, before invoking this method, a slice of identifiers was
created by looping over each dnsName. However, these identifiers were
solely used in error messages.

Segment the validation process into distinct parts for domain
validation, wildcard validation, and exact blocklist checks. This
approach eliminates the necessity of substituting *. with x. in wildcard
domains.

Introduce a new helper, ValidDomain. It checks that a domain is valid
and that it doesn't contain any invalid wildcard characters.
Functionality from the previous ValidDomain is preserved in
ValidNonWildcardDomain.

Fixes #3323
2023-12-19 14:22:18 -05:00
Aaron Gable 5e1bc3b501
Simplify the features package (#7204)
Replace the current three-piece setup (enum of feature variables, map of
feature vars to default values, and autogenerated bidirectional maps of
feature variables to and from strings) with a much simpler one-piece
setup: a single struct with one boolean-typed field per feature. This
preserves the overall structure of the package -- a single global
feature set protected by a mutex, and Set, Reset, and Enabled methods --
although the exact function signatures have all changed somewhat.

The executable config format remains the same, so no deployment changes
are necessary. This change does deprecate the AllowUnrecognizedFeatures
feature, as we cannot tell the json config parser to ignore unknown
field names, but that flag is set to False in all of our deployment
environments already.

Fixes https://github.com/letsencrypt/boulder/issues/6802
Fixes https://github.com/letsencrypt/boulder/issues/5229
2023-12-12 15:51:57 -05:00
Aaron Gable 16081d8e30
Invert RequireCommonName into AllowNoCommonName (#7139)
The RequireCommonName feature flag was our only "inverted" feature flag,
which defaulted to true and had to be explicitly set to false. This
inversion can lead to confusion, especially to readers who expect all Go
default values to be zero values. We plan to remove the ability for our
feature flag system to support default-true flags, which the existence
of this flag blocked. Since this flag has not been set in any real
configs, inverting it is easy.

Part of https://github.com/letsencrypt/boulder/issues/6802
2023-11-06 10:58:30 -08:00
Aaron Gable 276978ac4a
Lowercase CN in all code paths (#6824)
When returning a CN from csr.NamesFromCSR, ensure that we call
strings.ToLower on that name in all return paths. This prevents us from
running into lint failures (and therefore refusing to issue) when an
applicant submits a CSR containing uppercase SANs and no explicit CN.
2023-04-17 14:56:33 -04:00
Aaron Gable 94f93361a0
Promote the first SAN from the CSR (#6796)
Rather than promoting the alphabetically-first SAN to be the CN, promote
the SAN which came first in the CSR. This is a reversion to previous
behavior that was changed as a side-effect of:
- https://github.com/letsencrypt/boulder/pull/6706;
- https://github.com/letsencrypt/boulder/pull/6749; and
- https://github.com/letsencrypt/boulder/pull/6757

Fixes https://github.com/letsencrypt/boulder/issues/6801
2023-04-06 14:30:19 -07:00
Phil Porada 8a65f7104e
Force a new allocation for sans in NamesFromCSR (#6759)
In `csr.NamesFromCSR`, there's a subtle trap when appending to a slice.
We set `sans := csr.DNSNames` and then depending on the existence of a
CommonName, we append to sans which could mutate the backing array in
`csr.DNSNames`. Instead, we will force a new allocation meaning that
`sans` has its own pointer to a distinct memory unrelated to the pointer
of `csr.DNSNames`.

See this blog post too: https://build-your-own.org/blog/20230316_go_full_slice/
2023-03-21 14:06:18 -07:00
Aaron Gable 6d6f3632da
Change SetCommonName to RequireCommonName (#6749)
Change the SetCommonName flag, introduced in #6706, to
RequireCommonName. Rather than having the flag control both whether or
not a name is hoisted from the SANs into the CN *and* whether or not the
CA is willing to issue certs with no CN, this updated flag now only
controls the latter. By default, the new flag is true, and continues our
current behavior of failing issuance if we cannot set a CN in the cert.
When the flag is set to false, then we are willing to issue certificates
for which the CSR contains no CN and there is no SAN short enough to be
hoisted into the CN field.

When we have rolled out this change, we can move on to the next flag in
this series: HoistCommonName, which will control whether or not a SAN is
hoisted at all, effectively giving the CSRs (and therefore the clients)
full control over whether their certificate contains a SAN.

This change is safe because no environment explicitly sets the
SetCommonName flag to false yet.

Fixes #5112
2023-03-21 11:07:06 -07:00
Aaron Gable 9af4871e59
Add SetCommonName feature flag (#6706)
Add a new feature flag, `SetCommonName`, which defaults to `true`. In
this default state, no behavior changes.

When set to `false` on the CA, this flag will cause the CA to leave the
Subject commonName field of the certificate blank, as is recommended by
the Baseline Requirements Section 7.1.4.2.2(a).

Also slightly modify the behavior of the RA's `matchesCSR()` function,
to allow for both certificates that have a CN and certificates that
don't. It is not feasible to put this behavior behind the same
SetCommonName flag, because that would require an atomic deploy of both
the RA and the CA.

Obsoletes #5112
2023-03-09 13:31:55 -05:00
Aaron Gable 4f473edfa8
Deprecate 10 feature flags (#6502)
Deprecate these feature flags, which are consistently set in both prod
and staging and which we do not expect to change the value of ever
again:
- AllowReRevocation
- AllowV1Registration
- CheckFailedAuthorizationsFirst
- FasterNewOrdersRateLimit
- GetAuthzReadOnly
- GetAuthzUseIndex
- MozRevocationReasons
- RejectDuplicateCSRExtensions
- RestrictRSAKeySizes
- SHA1CSRs

Move each feature flag to the "deprecated" section of features.go.
Remove all references to these feature flags from Boulder application
code, and make the code they were guarding the only path. Deduplicate
tests which were testing both the feature-enabled and feature-disabled
code paths. Remove the flags from all config-next JSON configs (but
leave them in config ones until they're fully deleted, not just
deprecated). Finally, replace a few testdata CSRs used in CA tests,
because they had SHA1WithRSAEncryption signatures that are now rejected.

Fixes #5171 
Fixes #6476
Part of #5997
2022-11-14 09:24:50 -08:00
Aaron Gable 3000339dee
Reject CSRs with duplicate extensions (#6153)
This behavior will be on by default in go1.19, so let's turn
it on ourselves now to ensure there won't be any breakage
when we upgrade in August.
2022-06-17 13:13:30 -07:00
Jacob Hoffman-Andrews cf9df961ba
Add feature flags for upcoming deprecations (#6043)
This adds three features flags: SHA1CSRs, OldTLSOutbound, and
OldTLSInbound. Each controls the behavior of an upcoming deprecation
(except OldTLSInbound, which isn't yet scheduled for a deprecation
but will be soon). Note that these feature flags take advantage of
`features`' default values, so they can default to "true" (that is, each
of these features is enabled by default), and we set them to "false"
in the config JSON to turn them off when the time comes.

The unittest for OldTLSOutbound requires that `example.com` resolves
to 127.0.0.1. This is because there's logic in the VA that checks
that redirected-to hosts end in an IANA TLD. The unittest relies on
redirecting, and we can't use e.g. `localhost` in it because of that
TLD check, so we use example.com.

Fixes #6036 and #6037
2022-04-15 12:14:00 -07:00
Aaron Gable 305ef9cce9
Improve error checking paradigm (#5920)
We have decided that we don't like the if err := call(); err != nil
syntax, because it creates confusing scopes, but we have not cleaned up
all existing instances of that syntax. However, we have now found a
case where that syntax enables a bug: It caused readers to believe that
a later err = call() statement was assigning to an already-declared err
in the local scope, when in fact it was assigning to an
already-declared err in the parent scope of a closure. This caused our
ineffassign and staticcheck linters to be unable to analyze the
lifetime of the err variable, and so they did not complain when we
never checked the actual value of that error.

This change standardizes on the two-line error checking syntax
everywhere, so that we can more easily ensure that our linters are
correctly analyzing all error assignments.
2022-02-01 14:42:43 -07:00
Aaron Gable 8da52f74c3
Remove v1 `NewCertificate` code path from WFE and RA (#5842)
The NewCertificate codepath was the ACME v1 API's equivalent of
the modern Finalize endpoint. Remove the bodies of the WFE's and
the RA's `NewCertificate` functions. Remove the functions which were
called only from those functions. One of the removed functions is the
old `checkAuthorizations`, so update some tests which were calling
that directly to instead use different entry points.

Part of #5681
2021-12-13 17:45:45 -08:00
Roland Bracewell Shoemaker 7853b12cb3
Remove support for issuing certificates with no CN (#5008)
We'd like to issue certs with no CN eventually, but it's not
going to happen any time soon. In the mean time, the existing
code never gets exercised and is rather complex, so this
removes it.
2020-08-05 09:15:30 -07:00
Aaron Gable 4a85abf25a
Fix error types emitted by good_key.go (#4932)
The `KeyPolicy.GoodKey` method is used to validate both public keys
used to sign JWK messages, and public keys contained inside CSR
messages.

According to RFC8555 section 6.7, validation failure in the former
case should result in `badPublicKey`, while validation failure in
the latter case should result in `badCSR`. In either case, a failure
due to reasons other than the key itself should result in
`serverInternal`.

However, the GoodKey method returns a variety of different errors
which are not all applicable depending on the context in which it is
called. In addition, the `csr.VerifyCSR` method passes these errors
through verbatim, resulting in ACME clients receiving confusing and
incorrect error message types.

This change causes the GoodKey method to always return either a
generic error or a KeyError. Calling methods should treat a `KeyError`
as either a `badPublicKey` or a `badCSR` depending on their context,
and may treat a generic error however they choose (though likely as a
serverInternal error).

Fixes #4930
2020-07-06 10:06:10 -07:00
Roland Bracewell Shoemaker 9df97cbf06
Add a blocked keys table, and use it (#4773)
Fixes #4712 and fixes #4711.
2020-04-15 13:42:51 -07:00
Daniel McCarney ecca3492e9 csr: return berrors in VerifyCSR. (#4473)
This also adds the badCSR error type specified by RFC 8555. It is a natural fit for the errors in VerifyCSR that aren't covered by badPublicKey. The web package function for converting a berror to
a problem is updated for the new badCSR error type.

The callers (RA and CA) are updated to return the berrors from VerifyCSR as is instead of unconditionally wrapping them as a berrors.MalformedError instance. Unit/integration tests are updated accordingly.

Resolves #4418
2019-10-09 17:11:11 -07:00
Roland Bracewell Shoemaker 1c8cfb3cba Fix SAN to CN promotion (#4298)
Before #4275 if a CSR only contained SANs longer than the max CN limit
it would set the CN to one anyway and would cause the 'CN too long'
check to get triggered. After #4275 if all of the SANs were too long
the CN wouldn't get set and we didn't have a check for `forceCNFromSAN
&& cn == ""` which would allow empty CNs despite `forceCNFromSAN`
being set. This adds that check and a test for the corner case.
2019-06-26 15:34:47 -07:00
Daniel McCarney 4fbb90b2d1
csr: be more flexible promoting a SAN to Subj. CN. (#4275)
When configured to force promote a SAN to the Subject CN while
normalizing a CSR without a CN we should try to find a SAN that is <=
maxCNLength.
2019-06-20 14:18:37 -04:00
Daniel McCarney 7dd176e9a4 Implement suberrors for policy blocked names. (#4234)
When validating a CSR's identifiers, or a new order's identifiers there may be more than one identifier that is blocked by policy. We should return an error that has suberrors identifying each bad identifier individually in this case.

Updates https://github.com/letsencrypt/boulder/issues/4193
Resolves https://github.com/letsencrypt/boulder/issues/3727
2019-05-31 15:00:17 -07:00
Daniel McCarney ea9871de1e core: split identifier types into separate package. (#4225)
This will allow implementing sub-problems without creating a cyclic
dependency between `core` and `problems`.

The `identifier` package is somewhat small/single-purpose and in the
future we may want to move more "ACME" bits beyond the `identifier`
types into a dedicated package outside of `core`.
2019-05-23 13:24:41 -07:00
Roland Bracewell Shoemaker a9a0846ee9
Remove checks for deployed features (#3881)
Removes the checks for a handful of deployed feature flags in preparation for removing the flags entirely. Also moves all of the currently deprecated flags to a separate section of the flags list so they can be more easily removed once purged from production configs.

Fixes #3880.
2018-10-17 20:29:18 -07:00
Daniel McCarney 299e53b237 RA,CA: Refuse to start with MaxNames == 0. (#3634)
This commit updates the `boulder-ra` and `boulder-ca` commands to refuse
to start if their configured `MaxNames` is 0 (the default value). This
should always be set to a positive number.

This commit also updates `csr/csr.go` to always apply the max names
check since it will never be 0 after the change above.

Also refactor `FailOnError` to pull out a separate `Fail` function.

Related to https://github.com/letsencrypt/boulder/issues/3632
2018-04-10 10:53:23 -07:00
Daniel McCarney 1c99f91733 Policy based issuance for wildcard identifiers (Round two) (#3252)
This PR implements issuance for wildcard names in the V2 order flow. By policy, pending authorizations for wildcard names only receive a DNS-01 challenge for the base domain. We do not re-use authorizations for the base domain that do not come from a previous wildcard issuance (e.g. a normal authorization for example.com turned valid by way of a DNS-01 challenge will not be reused for a *.example.com order).

The wildcard prefix is stripped off of the authorization identifier value in two places:

When presenting the authorization to the user - ACME forbids having a wildcard character in an authorization identifier.
When performing validation - We validate the base domain name without the *. prefix.
This PR is largely a rewrite/extension of #3231. Instead of using a pseudo-challenge-type (DNS-01-Wildcard) to indicate an authorization & identifier correspond to the base name of a wildcard order name we instead allow the identifier to take the wildcard order name with the *. prefix.
2017-12-04 12:18:10 -08:00
Roland Bracewell Shoemaker 94e4947c58 Remove RSAPSS signatures from the list of acceptable CSR signing algs (#3079) 2017-09-13 14:07:20 -04:00
Roland Bracewell Shoemaker 11a2149746 Switch from badSignatureAlgorithms to goodSignatureAlgorithms (#2989)
In ca/certificate-authority.go, we previously had a block list of signature algorithms we will not accept for CSRs. This commit switches to an allowed list of signature algorithms that we will accept.
2017-08-17 08:55:07 -04:00
Jacob Hoffman-Andrews 404e9682b1 Improve error messages. (#2256)
Quote rejected hostnames.
Include term "global" when rejecting based on global rate limit.

Fixes #2252
2016-10-18 10:15:21 -07:00
Jacob Hoffman-Andrews 96fc0b264d Reject IPAddresses and EmailAddresses earlier. (#2213)
Previously, if we received a CSR with IPAddress or EmailAddress SANs, we would
ignore those fields, issuing only for the DNSNames in the CSR. However, we would
later check in MatchesCSR that the CSR's IPAddresses and EmailAddresses matches
those in the issued certificate. This check would fail, serving a 500 to the end
user.

Instead, we now reject the CSR earlier in the process, and send a
meaningful error message.

Fixes #2203
2016-10-03 10:22:44 -07:00
Roland Bracewell Shoemaker 91bfd05127 Revert #2088 (#2137)
* Remove oldx509 usage

* Un-vendor old crypto/x509, crypto/x509/pkix, and encoding/asn1
2016-08-23 14:01:37 -04:00
Jacob Hoffman-Andrews 474b76ad95 Import forked x509 for parsing of CSRs with empty integers (#2088)
Part of #2080.

This change vendors `crypto/x509`, `crypto/x509/pkix`, and `encoding/asn1` from  1d5f6a765d. That commit is a direct child of the Go 1.5.4 release tag, so it contains the same code as the current Go version we are using. In that commit I rewrote imports in those packages so they depend on each other internally rather than calling out to the standard library, which would cause type disagreements.

I changed the imports in each place where we're parsing CSRs, and imported under a different name `oldx509`, both to avoid collisions and make it clear what's going on. Places that only use `x509` to parse certificates are not changed, and will use the current standard library.

This will unblock us from moving to Go 1.6, and subsequently Go 1.7.
2016-07-28 10:38:33 -04:00
Ben Irving d3db851403 remove regID from WillingToIssue (#1957)
The `regID` parameter in the PA's `WillingToIssue` function was originally used for whitelisting purposes, but is not used any longer. This PR removes it.
2016-06-22 12:21:07 -04:00
Jacob Hoffman-Andrews 9a4b979397 Move goodkey and nonce out of core (#1869) 2016-06-02 11:29:58 -07:00
Roland Bracewell Shoemaker 5abe7e3cdf Move CSR normalization/verification to their own methods (#1826)
* Split CSR testing and name hoisting into own functions, verify CSR in RA & CA

* Move tests around and various other fixes

* 1.5.3 doesn't have the needed stringer

* Move functions to their own lib

* Remove unused imports

* Move MaxCNLength and BadSignatureAlgorithms to csr package

* Always normalizeCSR in VerifyCSR and de-export it

* Update comments
2016-05-26 14:17:41 -07:00