diff --git a/client.go b/client.go index 17f54b8..3a02351 100644 --- a/client.go +++ b/client.go @@ -139,7 +139,7 @@ func (c *Client) CACerts(ctx context.Context) ([]*x509.Certificate, error) { return nil, err } - if err := verifyResponseType(resp, mimeTypePKCS7, encodingTypeBase64); err != nil { + if err := verifyResponseType(resp, []string{mimeTypePKCS7}, encodingTypeBase64); err != nil { return nil, err } @@ -181,7 +181,7 @@ func (c *Client) CSRAttrs(ctx context.Context) (CSRAttrs, error) { return CSRAttrs{}, err } - if err := verifyResponseType(resp, mimeTypeCSRAttrs, encodingTypeBase64); err != nil { + if err := verifyResponseType(resp, []string{mimeTypeCSRAttrs, mimeTypePKCS7}, encodingTypeBase64); err != nil { return CSRAttrs{}, err } @@ -234,7 +234,7 @@ func (c *Client) enrollCommon(ctx context.Context, r *x509.CertificateRequest, r return nil, err } - if err := verifyResponseType(resp, mimeTypePKCS7, encodingTypeBase64); err != nil { + if err := verifyResponseType(resp, []string{mimeTypePKCS7}, encodingTypeBase64); err != nil { return nil, err } diff --git a/http.go b/http.go index a1c82d9..2e7ce71 100644 --- a/http.go +++ b/http.go @@ -234,18 +234,20 @@ func verifyPartType(part *multipart.Part, ct, ce, pos string) error { // verifyResponseType verifies if the content-type and content-transfer-encoding // of an HTTP response are as expected. It returns a normal error and is intended -// to be used by client code. -func verifyResponseType(r *http.Response, t, e string) error { +// to be used by client code. Multiple acceptable content types may be provided; +// the response content type must match at least one of them. +func verifyResponseType(r *http.Response, t []string, e string) error { ctype, _, err := mime.ParseMediaType(r.Header.Get(contentTypeHeader)) if err != nil { return fmt.Errorf("missing or malformed %s header: %w", contentTypeHeader, err) } - if !strings.HasPrefix(ctype, t) { - return fmt.Errorf("unexpected %s: %s", contentTypeHeader, ctype) + for _, accepted := range t { + if strings.HasPrefix(ctype, accepted) { + return nil + } } - - return nil + return fmt.Errorf("unexpected %s: %s", contentTypeHeader, ctype) } // verifyPartTypeResponse verifies if the content-type and content-transfer-encoding diff --git a/http_test.go b/http_test.go index 9ec8317..3e583f8 100644 --- a/http_test.go +++ b/http_test.go @@ -28,7 +28,7 @@ func TestVerifyResponseType(t *testing.T) { var testcases = []struct { name string r *http.Response - t string + t []string e string err error }{ @@ -40,7 +40,7 @@ func TestVerifyResponseType(t *testing.T) { "Content-Transfer-Encoding": []string{"BasE64"}, }, }, - t: "application/pkcs7", + t: []string{"application/pkcs7"}, e: "bASe64", }, { @@ -51,7 +51,7 @@ func TestVerifyResponseType(t *testing.T) { "Content-Transfer-Encoding": []string{"base64"}, }, }, - t: "application/pkcs10", + t: []string{"application/pkcs10"}, e: "base64", err: errors.New("unexpected Content-Type: application/pkcs7"), }, @@ -62,7 +62,7 @@ func TestVerifyResponseType(t *testing.T) { "Content-Transfer-Encoding": []string{"base64"}, }, }, - t: "application/pkcs7", + t: []string{"application/pkcs7"}, e: "base64", err: errors.New("missing or malformed Content-Type header: mime: no media type"), }, @@ -74,10 +74,44 @@ func TestVerifyResponseType(t *testing.T) { "Content-Transfer-Encoding": []string{"base64"}, }, }, - t: "application/pkcs7", + t: []string{"application/pkcs7"}, e: "base64", err: errors.New("missing or malformed Content-Type header: mime: invalid media parameter"), }, + { + name: "CSRAttrsRFC7030", + r: &http.Response{ + Header: http.Header{ + "Content-Type": []string{"application/pkcs7-mime"}, + "Content-Transfer-Encoding": []string{"base64"}, + }, + }, + t: []string{"application/csrattrs", "application/pkcs7-mime"}, + e: "base64", + }, + { + name: "CSRAttrsNonStandard", + r: &http.Response{ + Header: http.Header{ + "Content-Type": []string{"application/csrattrs"}, + "Content-Transfer-Encoding": []string{"base64"}, + }, + }, + t: []string{"application/csrattrs", "application/pkcs7-mime"}, + e: "base64", + }, + { + name: "CSRAttrsWrongType", + r: &http.Response{ + Header: http.Header{ + "Content-Type": []string{"application/pkcs10"}, + "Content-Transfer-Encoding": []string{"base64"}, + }, + }, + t: []string{"application/csrattrs", "application/pkcs7-mime"}, + e: "base64", + err: errors.New("unexpected Content-Type: application/pkcs10"), + }, } for _, tc := range testcases {