diff --git a/builtin/credential/aws-ec2/path_config_certificate.go b/builtin/credential/aws-ec2/path_config_certificate.go index caa56d5586..4613b21211 100644 --- a/builtin/credential/aws-ec2/path_config_certificate.go +++ b/builtin/credential/aws-ec2/path_config_certificate.go @@ -97,13 +97,14 @@ func pathConfigCertificate(b *backend) *framework.Path { Description: "AWS Public cert required to verify PKCS7 signature of the EC2 instance metadata.", }, "type": { - Type: framework.TypeString, + Type: framework.TypeString, + Default: "pkcs7", Description: ` Takes the value of either "pkcs7" or "identity", indicating the type of document which can be verified using the given certificate. The reason is that the PKCS#7 document will have a DSA digest and the identity signature will have an RSA signature, and accordingly the public certificates to verify those also -vary.`, +vary. Defaults to "pkcs7".`, }, }, @@ -351,18 +352,6 @@ func (b *backend) pathConfigCertificateCreateUpdate( return logical.ErrorResponse("missing certificate name"), nil } - certType := data.Get("type").(string) - if certType == "" { - return logical.ErrorResponse("missing certificate type"), nil - } - - switch strings.ToLower(certType) { - case "pkcs7": - case "identity": - default: - return logical.ErrorResponse("invalid certificate type"), nil - } - b.configMutex.Lock() defer b.configMutex.Unlock() @@ -375,6 +364,21 @@ func (b *backend) pathConfigCertificateCreateUpdate( certEntry = &awsPublicCert{} } + // Check if type information is provided + certTypeRaw, ok := data.GetOk("type") + if ok { + certEntry.Type = strings.ToLower(certTypeRaw.(string)) + } else if req.Operation == logical.CreateOperation { + certEntry.Type = data.Get("type").(string) + } + + switch certEntry.Type { + case "pkcs7": + case "identity": + default: + return logical.ErrorResponse(fmt.Sprintf("invalid certificate type %q", certEntry.Type)), nil + } + // Check if the value is provided by the client certStrData, ok := data.GetOk("aws_public_cert") if ok { @@ -403,9 +407,6 @@ func (b *backend) pathConfigCertificateCreateUpdate( return logical.ErrorResponse("invalid certificate; failed to decode and parse certificate"), nil } - // Add the certificate type to the storage entry - certEntry.Type = certType - // If none of the checks fail, save the provided certificate if err := b.nonLockedSetAWSPublicCertificateEntry(req.Storage, certName, certEntry); err != nil { return nil, err diff --git a/builtin/credential/aws-ec2/path_login.go b/builtin/credential/aws-ec2/path_login.go index 317bddb7a9..8f83101a22 100644 --- a/builtin/credential/aws-ec2/path_login.go +++ b/builtin/credential/aws-ec2/path_login.go @@ -221,9 +221,8 @@ func validateMetadata(clientNonce, pendingTime string, storedIdentity *whitelist // Verifies the integrity of the instance identity document using its SHA256 // RSA signature. After verification, returns the unmarshaled instance identity // document. -func (b *backend) verifyInstanceIdentitySignature(s logical.Storage, identity, signature string) (*identityDocument, error) { - identity = strings.TrimSpace(identity) - if identity == "" { +func (b *backend) verifyInstanceIdentitySignature(s logical.Storage, identityBytes []byte, signature string) (*identityDocument, error) { + if len(identityBytes) == 0 { return nil, fmt.Errorf("missing instance identity document") } @@ -248,10 +247,10 @@ func (b *backend) verifyInstanceIdentitySignature(s logical.Storage, identity, s // Check if any of the certs registered at the backend can verify the // signature for _, cert := range publicCerts { - err := cert.CheckSignature(x509.SHA256WithRSA, []byte(identity), []byte(signature)) + err := cert.CheckSignature(x509.SHA256WithRSA, identityBytes, []byte(signature)) if err == nil { var identityDoc identityDocument - if decErr := jsonutil.DecodeJSON([]byte(identity), &identityDoc); decErr != nil { + if decErr := jsonutil.DecodeJSON(identityBytes, &identityDoc); decErr != nil { return nil, decErr } return &identityDoc, nil @@ -321,13 +320,13 @@ func (b *backend) parseIdentityDocument(s logical.Storage, pkcs7B64 string) (*id func (b *backend) pathLoginUpdate( req *logical.Request, data *framework.FieldData) (*logical.Response, error) { identityDocB64 := data.Get("identity").(string) - identityDoc := "" + var identityDocBytes []byte + var err error if identityDocB64 != "" { - identityDocBytes, err := base64.StdEncoding.DecodeString(identityDocB64) - if err != nil { + identityDocBytes, err = base64.StdEncoding.DecodeString(identityDocB64) + if err != nil || len(identityDocBytes) == 0 { return logical.ErrorResponse("failed to base64 decode the instance identity document"), nil } - identityDoc = string(identityDocBytes) } signatureB64 := data.Get("signature").(string) @@ -345,15 +344,14 @@ func (b *backend) pathLoginUpdate( // Either the pkcs7 signature of the instance identity document, or // the identity document itself along with its SHA256 RSA signature // needs to be provided. - if pkcs7B64 == "" && (identityDoc == "" && signature == "") { + if pkcs7B64 == "" && (len(identityDocBytes) == 0 && signature == "") { return logical.ErrorResponse("either pkcs7 or a tuple containing the instance identity document and its SHA256 RSA signature needs to be provided"), nil - } else if pkcs7B64 != "" && (identityDoc != "" && signature != "") { + } else if pkcs7B64 != "" && (len(identityDocBytes) != 0 && signature != "") { return logical.ErrorResponse("both pkcs7 and a tuple containing the instance identity document and its SHA256 RSA signature is supplied; provide only one"), nil } // Verify the signature of the identity document and unmarshal it var identityDocParsed *identityDocument - var err error if pkcs7B64 != "" { identityDocParsed, err = b.parseIdentityDocument(req.Storage, pkcs7B64) if err != nil { @@ -363,7 +361,7 @@ func (b *backend) pathLoginUpdate( return logical.ErrorResponse("failed to verify the instance identity document using pkcs7"), nil } } else { - identityDocParsed, err = b.verifyInstanceIdentitySignature(req.Storage, identityDoc, signature) + identityDocParsed, err = b.verifyInstanceIdentitySignature(req.Storage, identityDocBytes, signature) if err != nil { return nil, err } diff --git a/website/source/docs/auth/aws-ec2.html.md b/website/source/docs/auth/aws-ec2.html.md index 419839ffa3..8eedef90fe 100644 --- a/website/source/docs/auth/aws-ec2.html.md +++ b/website/source/docs/auth/aws-ec2.html.md @@ -515,12 +515,12 @@ The response will be in JSON. For example: