Return errors on short PEM bundles (keys, issuers) (#16142)

* Return errors on short PEM bundles (keys, issuers)

When users pass the path of the bundle to the API, rather than the
contents of the bundle (say, by omitting the `@` symbol on a Vault CLI
request), give a better error message indicating to the user what the
potential problem might be. While a larger bound for certificates was
given (75 bytes, likely 100 would be fine as well), a smaller bound had
to be chosen for keys as there's less standard DER encoding data around
them.

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
This commit is contained in:
Alexander Scheel 2022-06-24 15:32:56 -04:00 committed by GitHub
parent 08f148ba42
commit 327963af03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 0 deletions

View File

@ -144,6 +144,21 @@ func (b *backend) pathImportIssuers(ctx context.Context, req *logical.Request, d
keysAllowed = false
pemBundle = certificate
}
if len(pemBundle) < 75 {
// It is almost nearly impossible to store a complete certificate in
// less than 75 bytes. It is definitely impossible to do so when PEM
// encoding has been applied. Detect this and give a better warning
// than "provided PEM block contained no data" in this case. This is
// because the PEM headers contain 5*4 + 6 + 4 + 2 + 2 = 34 characters
// minimum (five dashes, "BEGIN" + space + at least one character
// identifier, "END" + space + at least one character identifier, and
// a pair of new lines). That would leave 41 bytes for Base64 data,
// meaning at most a 30-byte DER certificate.
//
// However, < 75 bytes is probably a good length for a file path so
// suggest that is the case.
return logical.ErrorResponse("provided data for import was too short; perhaps a path was passed to the API rather than the contents of a PEM file"), nil
}
var createdKeys []string
var createdIssuers []string

View File

@ -194,6 +194,23 @@ func (b *backend) pathImportKeyHandler(ctx context.Context, req *logical.Request
return logical.ErrorResponse(err.Error()), nil
}
if len(pemBundle) < 64 {
// It is almost nearly impossible to store a complete key in
// less than 64 bytes. It is definitely impossible to do so when PEM
// encoding has been applied. Detect this and give a better warning
// than "provided PEM block contained no data" in this case. This is
// because the PEM headers contain 5*4 + 6 + 4 + 2 + 2 = 34 characters
// minimum (five dashes, "BEGIN" + space + at least one character
// identifier, "END" + space + at least one character identifier, and
// a pair of new lines). That would leave 30 bytes for Base64 data,
// meaning at most a 22-byte DER key. Even with a 128-bit key, 6 bytes
// is not sufficient for the required ASN.1 structure and OID encoding.
//
// However, < 64 bytes is probably a good length for a file path so
// suggest that is the case.
return logical.ErrorResponse("provided data for import was too short; perhaps a path was passed to the API rather than the contents of a PEM file"), nil
}
pemBytes := []byte(pemBundle)
var pemBlock *pem.Block