Skip to content
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

Vault-17911: add support for hex values in oid extension #21830

Merged
merged 3 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions builtin/credential/cert/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"github.com/hashicorp/go-sockaddr"
"io"
"io/ioutil"
"math/big"
Expand All @@ -28,8 +29,6 @@ import (
"time"

"github.com/go-test/deep"
"github.com/hashicorp/go-sockaddr"

"golang.org/x/net/http2"

cleanhttp "github.com/hashicorp/go-cleanhttp"
Expand Down Expand Up @@ -1306,6 +1305,10 @@ func TestBackend_ext_singleCert(t *testing.T) {
testAccStepLoginInvalid(t, connState),
testAccStepCert(t, "web", ca, "foo", allowed{names: "invalid", ext: "2.1.1.1:*,2.1.1.2:The Wrong Value"}, false),
testAccStepLoginInvalid(t, connState),
testAccStepCert(t, "web", ca, "foo", allowed{names: "example.com", ext: "hex:2.5.29.17:*87047F000002*"}, false),
testAccStepLoginInvalid(t, connState),
testAccStepCert(t, "web", ca, "foo", allowed{names: "example.com", ext: "hex:2.5.29.17:*87047F000001*"}, false),
testAccStepLogin(t, connState),
testAccStepReadConfig(t, config{EnableIdentityAliasMetadata: false}, connState),
testAccStepCert(t, "web", ca, "foo", allowed{metadata_ext: "2.1.1.1,1.2.3.45"}, false),
testAccStepLoginWithMetadata(t, connState, "web", map[string]string{"2-1-1-1": "A UTF8String Extension"}, false),
Expand Down
21 changes: 17 additions & 4 deletions builtin/credential/cert/path_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"crypto/x509"
"encoding/asn1"
"encoding/base64"
"encoding/hex"
"encoding/pem"
"errors"
"fmt"
Expand Down Expand Up @@ -507,17 +508,29 @@ func (b *backend) matchesCertificateExtensions(clientCert *x509.Certificate, con
// including its ASN.1 type tag bytes. For the sake of simplicity, assume string type
// and drop the tag bytes. And get the number of bytes from the tag.
clientExtMap := make(map[string]string, len(clientCert.Extensions))
hexExtMap := make(map[string]string, len(clientCert.Extensions))

for _, ext := range clientCert.Extensions {
var parsedValue string
asn1.Unmarshal(ext.Value, &parsedValue)
cipherboy marked this conversation as resolved.
Show resolved Hide resolved
clientExtMap[ext.Id.String()] = parsedValue
hexExtMap[ext.Id.String()] = hex.EncodeToString(ext.Value)
}
// If any of the required extensions don'log match the constraint fails

// If any of the required extensions don't match the constraint fails
for _, requiredExt := range config.Entry.RequiredExtensions {
reqExt := strings.SplitN(requiredExt, ":", 2)
cipherboy marked this conversation as resolved.
Show resolved Hide resolved
clientExtValue, clientExtValueOk := clientExtMap[reqExt[0]]
if !clientExtValueOk || !glob.Glob(reqExt[1], clientExtValue) {
return false
if reqExt[0] == "hex" {
reqHexExt := strings.SplitN(reqExt[1], ":", 2)
clientExtValue, clientExtValueOk := hexExtMap[reqHexExt[0]]
if !clientExtValueOk || !glob.Glob(strings.ToLower(reqHexExt[1]), clientExtValue) {
return false
}
} else {
clientExtValue, clientExtValueOk := clientExtMap[reqExt[0]]
if !clientExtValueOk || !glob.Glob(reqExt[1], clientExtValue) {
return false
}
}
}
return true
Expand Down
3 changes: 3 additions & 0 deletions changelog/21830.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
auth/cert: Adds support for requiring hexadecimal-encoded non-string certificate extension values
```
5 changes: 3 additions & 2 deletions website/content/api-docs/auth/cert.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ Sets a CA cert and associated parameters in a role name.
- `required_extensions` `(string: "" or array: [])` - Require specific Custom
Extension OIDs to exist and match the pattern. Value is a comma separated
string or array of `oid:value`. Expects the extension value to be some type
of ASN1 encoded string. All conditions _must_ be met. Supports globbing on
`value`.
of ASN1 encoded string. All conditions _must_ be met. To match on the hex-encoded
value of the extension, including non-string extensions, use the format
`hex:<oid>:<value>`.Supports globbing on `value`.
- `allowed_metadata_extensions` `(array:[])` - A comma separated string or
array of oid extensions. Upon successful authentication, these extensions
will be added as metadata if they are present in the certificate. The
Expand Down