Skip to content

Commit

Permalink
Merge pull request #9 from RealImage/decode-header
Browse files Browse the repository at this point in the history
Decode url-encoded mtls leaf certificate header from AWS ALB
  • Loading branch information
ananthb authored Apr 9, 2024
2 parents 02fd83d + 9212a1e commit 0215740
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 32 deletions.
24 changes: 19 additions & 5 deletions asgard/heimdallr.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ import (
"encoding/pem"
"log/slog"
"net/http"
"net/url"

"github.com/RealImage/bifrost"
"github.com/google/uuid"
)

const errBadAuthHeader = "missing or invalid authorization information, server is misconfigured"

type keyClientCert struct{}

// ClientCert returns the client certificate from the request context.
Expand All @@ -37,10 +40,21 @@ func Heimdallr(h HeaderName, ns uuid.UUID) func(http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

certPEM := r.Header.Get(h.String())
if certPEM == "" {
certHeader := r.Header.Get(h.String())
if certHeader == "" {
slog.ErrorContext(ctx, "missing authorization header")
http.Error(w, "missing authorization header", http.StatusUnauthorized)
http.Error(w, errBadAuthHeader, http.StatusServiceUnavailable)
return
}

certPEM, err := url.PathUnescape(certHeader)
if err != nil {
slog.ErrorContext(
ctx, "error decoding header",
"headerName", h.String(),
"headerValue", certHeader,
)
http.Error(w, errBadAuthHeader, http.StatusServiceUnavailable)
return
}

Expand All @@ -51,14 +65,14 @@ func Heimdallr(h HeaderName, ns uuid.UUID) func(http.Handler) http.Handler {
"headerName", h.String(),
"headerValue", certPEM,
)
http.Error(w, "invalid authorization header", http.StatusUnauthorized)
http.Error(w, errBadAuthHeader, http.StatusServiceUnavailable)
return
}

cert, err := bifrost.ParseCertificate(block.Bytes)
if err != nil {
slog.ErrorContext(ctx, "error parsing client certificate", "error", err)
http.Error(w, "invalid authorization header", http.StatusUnauthorized)
http.Error(w, errBadAuthHeader, http.StatusServiceUnavailable)
return
}

Expand Down
30 changes: 3 additions & 27 deletions asgard/heimdallr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,43 +41,19 @@ var heimdallrTestCases = []struct {
expectedNs uuid.UUID
}{
{
headerValue: `-----BEGIN CERTIFICATE-----
MIICCjCCAbCgAwIBAgIIH7lebxROSBQwCgYIKoZIzj0EAwIwXjEtMCsGA1UEAwwk
ZWZlYmJmZGMtZWMwNi01NjNmLWI4ZjItYjM5M2I0MjBkNWFlMS0wKwYDVQQKDCQw
MTg4MUM4Qy1FMkUxLTQ5NTAtOURFRS0zQTk1NThDNkM3NDEwIBcNMjQwMjE0MTkz
MDM1WhgPMjEwOTExMTAyMzAwMDBaMF4xLTArBgNVBAoTJDAxODgxYzhjLWUyZTEt
NDk1MC05ZGVlLTNhOTU1OGM2Yzc0MTEtMCsGA1UEAxMkYWUyZTg5ZDUtZGFiYi01
YTE1LWJhOTAtZWZmYzgzZmI3NzY0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
hEo7+i7dB9WnliZorIEWistXAgrHrtOz2rW0LaXIZcJNiEUAWkTzMFKrY0JZPVBo
UEXgYGHhV7hc3Id/+X4H9qNWMFQwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoG
CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUyi+UDUP7bQBmCVBM
jB+jvMHvmPQwCgYIKoZIzj0EAwIDSAAwRQIgOzVtg9kWc0BRJB2/JVDGAdjp6ozZ
5XuF6SBT/Xd57OoCIQDiAXXDOGBHEoNxSo+oz20OzretMmtk6htl0UU1bzL6Lw==
-----END CERTIFICATE-----`,
headerValue: "-----BEGIN%20CERTIFICATE-----%0AMIICCjCCAbCgAwIBAgIIH7lebxROSBQwCgYIKoZIzj0EAwIwXjEtMCsGA1UEAwwk%0AZWZlYmJmZGMtZWMwNi01NjNmLWI4ZjItYjM5M2I0MjBkNWFlMS0wKwYDVQQKDCQw%0AMTg4MUM4Qy1FMkUxLTQ5NTAtOURFRS0zQTk1NThDNkM3NDEwIBcNMjQwMjE0MTkz%0AMDM1WhgPMjEwOTExMTAyMzAwMDBaMF4xLTArBgNVBAoTJDAxODgxYzhjLWUyZTEt%0ANDk1MC05ZGVlLTNhOTU1OGM2Yzc0MTEtMCsGA1UEAxMkYWUyZTg5ZDUtZGFiYi01%0AYTE1LWJhOTAtZWZmYzgzZmI3NzY0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE%0AhEo7+i7dB9WnliZorIEWistXAgrHrtOz2rW0LaXIZcJNiEUAWkTzMFKrY0JZPVBo%0AUEXgYGHhV7hc3Id%2F+X4H9qNWMFQwDgYDVR0PAQH%2FBAQDAgWgMBMGA1UdJQQMMAoG%0ACCsGAQUFBwMCMAwGA1UdEwEB%2FwQCMAAwHwYDVR0jBBgwFoAUyi+UDUP7bQBmCVBM%0AjB+jvMHvmPQwCgYIKoZIzj0EAwIDSAAwRQIgOzVtg9kWc0BRJB2%2FJVDGAdjp6ozZ%0A5XuF6SBT%2FXd57OoCIQDiAXXDOGBHEoNxSo+oz20OzretMmtk6htl0UU1bzL6Lw==%0A-----END%20CERTIFICATE-----",
expectedKey: testPubKey,
expectedNs: uuid.MustParse("01881C8C-E2E1-4950-9DEE-3A9558C6C741"),
expectedCode: http.StatusOK,
},
{
headerValue: `-----BEGIN CERTIFICATE-----
MIICCTCCAbCgAwIBAgIIUKQb43DFdCEwCgYIKoZIzj0EAwIwXjEtMCsGA1UEAwwk
ZWZlYmJmZGMtZWMwNi01NjNmLWI4ZjItYjM5M2I0MjBkNWFlMS0wKwYDVQQKDCQw
MTg4MUM4Qy1FMkUxLTQ5NTAtOURFRS0zQTk1NThDNkM3NDEwIBcNMjQwMjE0MTkz
NDQwWhgPMjEwOTExMTAyMzAwMDBaMF4xLTArBgNVBAoTJDAxODgxYzhjLWUyZTEt
NDk1MC05ZGVlLTNhOTU1OGM2Yzc0MTEtMCsGA1UEAxMkYWUyZTg5ZDUtZGFiYi01
YTE1LWJhOTAtZWZmYzgzZmI3NzY0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
hEo7+i7dB9WnliZorIEWistXAgrHrtOz2rW0LaXIZcJNiEUAWkTzMFKrY0JZPVBo
UEXgYGHhV7hc3Id/+X4H9qNWMFQwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoG
CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUyi+UDUP7bQBmCVBM
jB+jvMHvmPQwCgYIKoZIzj0EAwIDRwAwRAIgREgMNY2MSwKL3YVMyzgI4h/0/0au
cpzcvv0u+i6cXHYCIGNqQgPElDasZfpAqS50msAs7yeTtZvBb396sZ+ZgJtk
-----END CERTIFICATE-----`,
headerValue: "-----BEGIN%20CERTIFICATE-----%0AMIICCTCCAbCgAwIBAgIIUKQb43DFdCEwCgYIKoZIzj0EAwIwXjEtMCsGA1UEAwwk%0AZWZlYmJmZGMtZWMwNi01NjNmLWI4ZjItYjM5M2I0MjBkNWFlMS0wKwYDVQQKDCQw%0AMTg4MUM4Qy1FMkUxLTQ5NTAtOURFRS0zQTk1NThDNkM3NDEwIBcNMjQwMjE0MTkz%0ANDQwWhgPMjEwOTExMTAyMzAwMDBaMF4xLTArBgNVBAoTJDAxODgxYzhjLWUyZTEt%0ANDk1MC05ZGVlLTNhOTU1OGM2Yzc0MTEtMCsGA1UEAxMkYWUyZTg5ZDUtZGFiYi01%0AYTE1LWJhOTAtZWZmYzgzZmI3NzY0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE%0AhEo7+i7dB9WnliZorIEWistXAgrHrtOz2rW0LaXIZcJNiEUAWkTzMFKrY0JZPVBo%0AUEXgYGHhV7hc3Id%2F+X4H9qNWMFQwDgYDVR0PAQH%2FBAQDAgWgMBMGA1UdJQQMMAoG%0ACCsGAQUFBwMCMAwGA1UdEwEB%2FwQCMAAwHwYDVR0jBBgwFoAUyi+UDUP7bQBmCVBM%0AjB+jvMHvmPQwCgYIKoZIzj0EAwIDRwAwRAIgREgMNY2MSwKL3YVMyzgI4h%2F0%2F0au%0Acpzcvv0u+i6cXHYCIGNqQgPElDasZfpAqS50msAs7yeTtZvBb396sZ+ZgJtk%0A-----END%20CERTIFICATE-----",
expectedNs: uuid.MustParse("b9289da7-8813-51ed-957b-b6bc5a4d6416"),
expectedCode: http.StatusForbidden,
},
{
headerValue: "invalid json",
expectedCode: http.StatusUnauthorized,
expectedCode: http.StatusServiceUnavailable,
},
}

Expand Down

0 comments on commit 0215740

Please sign in to comment.