mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-29 17:52:32 +00:00
163 lines
7.0 KiB
Go
163 lines
7.0 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package issuing
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/ecdsa"
|
|
"crypto/ed25519"
|
|
"crypto/elliptic"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/asn1"
|
|
"errors"
|
|
)
|
|
|
|
// DER encoded RSA PSS parameters for the
|
|
// SHA256, SHA384, and SHA512 hashes as defined in RFC 3447, Appendix A.2.3.
|
|
// The parameters contain the following values:
|
|
// - hashAlgorithm contains the associated hash identifier with NULL parameters
|
|
// - maskGenAlgorithm always contains the default mgf1SHA1 identifier
|
|
// - saltLength contains the length of the associated hash
|
|
// - trailerField always contains the default trailerFieldBC value
|
|
var (
|
|
pssParametersSHA256 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 162, 3, 2, 1, 32}}
|
|
pssParametersSHA384 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 162, 3, 2, 1, 48}}
|
|
pssParametersSHA512 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 162, 3, 2, 1, 64}}
|
|
)
|
|
|
|
var (
|
|
emptyRawValue = asn1.RawValue{}
|
|
|
|
oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
|
|
oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
|
|
oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
|
|
oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
|
|
oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
|
|
oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
|
|
oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
|
|
oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
|
|
oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2}
|
|
oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
|
|
oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
|
|
oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
|
|
oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
|
|
oidSignatureEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
|
|
oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29}
|
|
|
|
signatureAlgorithmDetails = []struct {
|
|
algo x509.SignatureAlgorithm
|
|
name string
|
|
oid asn1.ObjectIdentifier
|
|
params asn1.RawValue
|
|
pubKeyAlgo x509.PublicKeyAlgorithm
|
|
hash crypto.Hash
|
|
isRSAPSS bool
|
|
}{
|
|
{x509.MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, asn1.NullRawValue, x509.RSA, crypto.MD5, false},
|
|
{x509.SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, asn1.NullRawValue, x509.RSA, crypto.SHA1, false},
|
|
{x509.SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, asn1.NullRawValue, x509.RSA, crypto.SHA1, false},
|
|
{x509.SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, asn1.NullRawValue, x509.RSA, crypto.SHA256, false},
|
|
{x509.SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, asn1.NullRawValue, x509.RSA, crypto.SHA384, false},
|
|
{x509.SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, asn1.NullRawValue, x509.RSA, crypto.SHA512, false},
|
|
{x509.SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, pssParametersSHA256, x509.RSA, crypto.SHA256, true},
|
|
{x509.SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, pssParametersSHA384, x509.RSA, crypto.SHA384, true},
|
|
{x509.SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, pssParametersSHA512, x509.RSA, crypto.SHA512, true},
|
|
{x509.DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, emptyRawValue, x509.DSA, crypto.SHA1, false},
|
|
{x509.DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, emptyRawValue, x509.DSA, crypto.SHA256, false},
|
|
{x509.ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, emptyRawValue, x509.ECDSA, crypto.SHA1, false},
|
|
{x509.ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, emptyRawValue, x509.ECDSA, crypto.SHA256, false},
|
|
{x509.ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, emptyRawValue, x509.ECDSA, crypto.SHA384, false},
|
|
{x509.ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, emptyRawValue, x509.ECDSA, crypto.SHA512, false},
|
|
{x509.PureEd25519, "Ed25519", oidSignatureEd25519, emptyRawValue, x509.Ed25519, crypto.Hash(0) /* no pre-hashing */, false},
|
|
}
|
|
)
|
|
|
|
// SigningParamsForKey returns the signature algorithm and its Algorithm
|
|
// Identifier to use for signing, based on the key type. If sigAlgo is not zero
|
|
// then it overrides the default.
|
|
// This function is copied from crypto/x509/x509.go in the Go standard library.
|
|
func SigningParamsForKey(key crypto.Signer, sigAlgo x509.SignatureAlgorithm) (x509.SignatureAlgorithm, pkix.AlgorithmIdentifier, error) {
|
|
var ai pkix.AlgorithmIdentifier
|
|
var pubType x509.PublicKeyAlgorithm
|
|
var defaultAlgo x509.SignatureAlgorithm
|
|
|
|
switch pub := key.Public().(type) {
|
|
case *rsa.PublicKey:
|
|
pubType = x509.RSA
|
|
defaultAlgo = x509.SHA256WithRSA
|
|
|
|
case *ecdsa.PublicKey:
|
|
pubType = x509.ECDSA
|
|
switch pub.Curve {
|
|
case elliptic.P224(), elliptic.P256():
|
|
defaultAlgo = x509.ECDSAWithSHA256
|
|
case elliptic.P384():
|
|
defaultAlgo = x509.ECDSAWithSHA384
|
|
case elliptic.P521():
|
|
defaultAlgo = x509.ECDSAWithSHA512
|
|
default:
|
|
return 0, ai, errors.New("x509: unsupported elliptic curve")
|
|
}
|
|
|
|
case ed25519.PublicKey:
|
|
pubType = x509.Ed25519
|
|
defaultAlgo = x509.PureEd25519
|
|
|
|
default:
|
|
return 0, ai, errors.New("x509: only RSA, ECDSA and Ed25519 keys supported")
|
|
}
|
|
|
|
if sigAlgo == 0 {
|
|
sigAlgo = defaultAlgo
|
|
}
|
|
|
|
for _, details := range signatureAlgorithmDetails {
|
|
if details.algo == sigAlgo {
|
|
if details.pubKeyAlgo != pubType {
|
|
return 0, ai, errors.New("x509: requested SignatureAlgorithm does not match private key type")
|
|
}
|
|
if details.hash == crypto.MD5 {
|
|
return 0, ai, errors.New("x509: signing with MD5 is not supported")
|
|
}
|
|
|
|
return sigAlgo, pkix.AlgorithmIdentifier{
|
|
Algorithm: details.oid,
|
|
Parameters: details.params,
|
|
}, nil
|
|
}
|
|
}
|
|
|
|
return 0, ai, errors.New("x509: unknown SignatureAlgorithm")
|
|
}
|
|
|
|
func DoesPublicKeyAlgoMatchSignatureAlgo(pubKey x509.PublicKeyAlgorithm, algo x509.SignatureAlgorithm) bool {
|
|
for _, detail := range signatureAlgorithmDetails {
|
|
if detail.algo == algo {
|
|
return pubKey == detail.pubKeyAlgo
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func IsRSAPSS(algo x509.SignatureAlgorithm) bool {
|
|
for _, details := range signatureAlgorithmDetails {
|
|
if details.algo == algo {
|
|
return details.isRSAPSS
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func HashFunc(algo x509.SignatureAlgorithm) crypto.Hash {
|
|
for _, details := range signatureAlgorithmDetails {
|
|
if details.algo == algo {
|
|
return details.hash
|
|
}
|
|
}
|
|
return crypto.Hash(0)
|
|
}
|