Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions pkg/policy/policySpecification_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,55 @@ func TestBuildPolicySpecificationForTPPLocked(t *testing.T) {
}
}

// TestBuildPolicySpecificationForTPPPkixParameterSet covers TPP 25.1+ policy folders, which lock
// allowed key algorithms via KeyPair.PkixParameterSet.Values instead of the deprecated
// KeyAlgorithm/KeySize/EllipticCurve Locked flags.
func TestBuildPolicySpecificationForTPPPkixParameterSet(t *testing.T) {
tppPolicy := getPolicyResponse(true)
tppPolicy.KeyPairResponse.PkixParameterSet = LockedArrayAttribute{
Locked: true,
Value: []string{
"1.3.6.1.4.1.28783.10.1.1.4096",
"1.3.6.1.4.1.28783.10.1.1.8192",
},
}

ps, err := BuildPolicySpecificationForTPP(CheckPolicyResponse{Policy: &tppPolicy})
if err != nil {
t.Fatalf("Error building policy specification \nError: %s", err)
}

if ps.Policy == nil || ps.Policy.KeyPair == nil {
t.Fatal("expected a key pair policy to be set")
}
keyPair := ps.Policy.KeyPair
if len(keyPair.KeyTypes) != 1 || keyPair.KeyTypes[0] != "RSA" {
t.Fatalf("expected KeyTypes [RSA], got %v", keyPair.KeyTypes)
}
if len(keyPair.RsaKeySizes) != 2 || keyPair.RsaKeySizes[0] != 4096 || keyPair.RsaKeySizes[1] != 8192 {
t.Fatalf("expected RsaKeySizes [4096 8192], got %v", keyPair.RsaKeySizes)
}
if len(keyPair.EllipticCurves) != 0 {
t.Fatalf("expected no EllipticCurves, got %v", keyPair.EllipticCurves)
}
}

func TestBuildPolicySpecificationForTPPPkixParameterSetUnrecognisedOID(t *testing.T) {
tppPolicy := getPolicyResponse(true)
tppPolicy.KeyPairResponse.PkixParameterSet = LockedArrayAttribute{
Locked: true,
Value: []string{"1.2.3.4.5"},
}

_, err := BuildPolicySpecificationForTPP(CheckPolicyResponse{Policy: &tppPolicy})
if err == nil {
t.Fatal("expected an error for an unrecognised PKIX parameter set OID")
}
if !strings.Contains(err.Error(), "unrecognised PKIX parameter set OID") {
t.Fatalf("unexpected error message: %v", err)
}
}

func TestGetZoneInfo(t *testing.T) {
originalAPP := "DevOps"
originalCit := "Open Source"
Expand Down
5 changes: 5 additions & 0 deletions pkg/policy/policyStructures.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ type KeyPairResponse struct {
KeyAlgorithm LockedAttribute `json:"KeyAlgorithm"`
KeySize LockedIntAttribute `json:"KeySize"`
EllipticCurve LockedAttribute `json:"EllipticCurve"`
// PkixParameterSet lists the PKIX OIDs of the key algorithms allowed by policy. Available
// from TPP 25.1 onwards, it supersedes KeyAlgorithm/KeySize/EllipticCurve above, which TPP
// no longer locks once a policy folder's allowed algorithms are configured via the newer
// AlgorithmSelector API.
PkixParameterSet LockedArrayAttribute `json:"PkixParameterSet"`
}

type SubjectResponse struct {
Expand Down
94 changes: 71 additions & 23 deletions pkg/policy/policyUtils.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var KeyAlgorithmsToPKIX = map[string]map[string]string{
"2048": "1.3.6.1.4.1.28783.10.1.1.2048",
"3072": "1.3.6.1.4.1.28783.10.1.1.3072",
"4096": "1.3.6.1.4.1.28783.10.1.1.4096",
"8192": "1.3.6.1.4.1.28783.10.1.1.8192",
},
"ECC": {
"P256": "1.3.6.1.4.1.28783.10.2.1.256",
Expand All @@ -39,6 +40,27 @@ var KeyAlgorithmsToPKIX = map[string]map[string]string{
},
}

// PkixOidKeyAlgorithm describes the key type/size/curve represented by a PKIX parameter set OID.
type PkixOidKeyAlgorithm struct {
KeyType string // "RSA" or "ECDSA"
KeySize int // populated for RSA
Curve string // populated for ECDSA, e.g. "P256"
}

// PkixToKeyAlgorithms is the reverse of KeyAlgorithmsToPKIX: it maps a PKIX parameter set OID, as
// returned by TPP 25.1+'s AlgorithmSelector API (and surfaced via Certificates/CheckPolicy's
// KeyPair.PkixParameterSet.Values), back to the key type/size/curve it represents.
var PkixToKeyAlgorithms = map[string]PkixOidKeyAlgorithm{
"1.3.6.1.4.1.28783.10.1.1.1024": {KeyType: "RSA", KeySize: 1024},
"1.3.6.1.4.1.28783.10.1.1.2048": {KeyType: "RSA", KeySize: 2048},
"1.3.6.1.4.1.28783.10.1.1.3072": {KeyType: "RSA", KeySize: 3072},
"1.3.6.1.4.1.28783.10.1.1.4096": {KeyType: "RSA", KeySize: 4096},
"1.3.6.1.4.1.28783.10.1.1.8192": {KeyType: "RSA", KeySize: 8192},
"1.3.6.1.4.1.28783.10.2.1.256": {KeyType: "ECDSA", Curve: "P256"},
"1.3.6.1.4.1.28783.10.2.1.384": {KeyType: "ECDSA", Curve: "P384"},
"1.3.6.1.4.1.28783.10.2.1.521": {KeyType: "ECDSA", Curve: "P521"},
}

func GetFileType(f string) string {
extension := filepath.Ext(f)

Expand Down Expand Up @@ -596,34 +618,60 @@ func BuildPolicySpecificationForTPP(checkPolicyResp CheckPolicyResponse) (*Polic

//resolve key pair's attributes

//resolve keyTypes
if policy.KeyPairResponse.KeyAlgorithm.Value != "" {
if policy.KeyPairResponse.KeyAlgorithm.Locked {
keyPair.KeyTypes = []string{policy.KeyPairResponse.KeyAlgorithm.Value}
} else {
shouldCreateDefKeyPair = true
defaultKeyPair.KeyType = &policy.KeyPairResponse.KeyAlgorithm.Value
}
}

if strings.ToUpper(policy.KeyPairResponse.KeyAlgorithm.Value) == "RSA" {
//resolve rsaKeySizes
if policy.KeyPairResponse.KeySize.Value > 0 {
if policy.KeyPairResponse.KeySize.Locked {
keyPair.RsaKeySizes = []int{policy.KeyPairResponse.KeySize.Value}
} else {
shouldCreateDefKeyPair = true
defaultKeyPair.RsaKeySize = &policy.KeyPairResponse.KeySize.Value
if policy.KeyPairResponse.PkixParameterSet.Locked && len(policy.KeyPairResponse.PkixParameterSet.Value) > 0 {
//TPP 25.1+: allowed key algorithms are locked via the PKIX parameter set OID list rather
//than the deprecated KeyAlgorithm/KeySize/EllipticCurve fields below.
var keyTypes []string
var rsaKeySizes []int
var curves []string
for _, oid := range policy.KeyPairResponse.PkixParameterSet.Value {
alg, ok := PkixToKeyAlgorithms[oid]
if !ok {
return nil, fmt.Errorf("policy allows unrecognised PKIX parameter set OID %q; vcert's OID table may need updating", oid)
}
if !existValueInArray(keyTypes, alg.KeyType) {
keyTypes = append(keyTypes, alg.KeyType)
}
switch alg.KeyType {
case "RSA":
rsaKeySizes = append(rsaKeySizes, alg.KeySize)
case "ECDSA":
curves = append(curves, alg.Curve)
}
}
keyPair.KeyTypes = keyTypes
keyPair.RsaKeySizes = rsaKeySizes
keyPair.EllipticCurves = curves
} else {
//resolve ellipticCurve
if policy.KeyPairResponse.EllipticCurve.Value != "" {
if policy.KeyPairResponse.EllipticCurve.Locked {
keyPair.EllipticCurves = []string{policy.KeyPairResponse.EllipticCurve.Value}
//resolve keyTypes
if policy.KeyPairResponse.KeyAlgorithm.Value != "" {
if policy.KeyPairResponse.KeyAlgorithm.Locked {
keyPair.KeyTypes = []string{policy.KeyPairResponse.KeyAlgorithm.Value}
} else {
shouldCreateDefKeyPair = true
defaultKeyPair.EllipticCurve = &policy.KeyPairResponse.EllipticCurve.Value
defaultKeyPair.KeyType = &policy.KeyPairResponse.KeyAlgorithm.Value
}
}

if strings.ToUpper(policy.KeyPairResponse.KeyAlgorithm.Value) == "RSA" {
//resolve rsaKeySizes
if policy.KeyPairResponse.KeySize.Value > 0 {
if policy.KeyPairResponse.KeySize.Locked {
keyPair.RsaKeySizes = []int{policy.KeyPairResponse.KeySize.Value}
} else {
shouldCreateDefKeyPair = true
defaultKeyPair.RsaKeySize = &policy.KeyPairResponse.KeySize.Value
}
}
} else {
//resolve ellipticCurve
if policy.KeyPairResponse.EllipticCurve.Value != "" {
if policy.KeyPairResponse.EllipticCurve.Locked {
keyPair.EllipticCurves = []string{policy.KeyPairResponse.EllipticCurve.Value}
} else {
shouldCreateDefKeyPair = true
defaultKeyPair.EllipticCurve = &policy.KeyPairResponse.EllipticCurve.Value
}
}
}
}
Expand Down
51 changes: 50 additions & 1 deletion pkg/venafi/tpp/tpp.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/Venafi/vcert/v5/pkg/certificate"
"github.com/Venafi/vcert/v5/pkg/endpoint"
headers "github.com/Venafi/vcert/v5/pkg/httputils"
"github.com/Venafi/vcert/v5/pkg/policy"
)

const defaultKeySize = 2048
Expand Down Expand Up @@ -828,6 +829,14 @@ type serverPolicy struct {
Locked bool
Value string
}
// PkixParameterSet lists the PKIX OIDs of the key algorithms allowed by policy. Available
// from TPP 25.1 onwards, it supersedes KeyAlgorithm/KeySize/EllipticCurve above, which TPP
// no longer locks once a policy folder's allowed algorithms are configured via the newer
// AlgorithmSelector API.
PkixParameterSet struct {
Locked bool
Values []string
}
}
ManagementType _strValue

Expand All @@ -853,6 +862,40 @@ type serverPolicy struct {
WildcardsAllowed bool
}

// allowedKeyConfigurationsFromPkixParameterSet decodes a list of PKIX parameter set OIDs, as returned by
// TPP 25.1+'s Certificates/CheckPolicy KeyPair.PkixParameterSet.Values, into AllowedKeyConfigurations.
// The OID table (policy.PkixToKeyAlgorithms) is shared with pkg/policy's getpolicy/setpolicy CLI path,
// which decodes the same OIDs from the same TPP API family.
func allowedKeyConfigurationsFromPkixParameterSet(oids []string) ([]endpoint.AllowedKeyConfiguration, error) {
var rsaSizes []int
var curves []certificate.EllipticCurve
for _, oid := range oids {
entry, ok := policy.PkixToKeyAlgorithms[oid]
if !ok {
return nil, fmt.Errorf("tpp: policy allows unrecognised PKIX parameter set OID %q; vcert's OID table may need updating", oid)
}
switch entry.KeyType {
case "RSA":
rsaSizes = append(rsaSizes, entry.KeySize)
case "ECDSA":
var curve certificate.EllipticCurve
if err := curve.Set(entry.Curve); err != nil {
return nil, fmt.Errorf("tpp: policy allows PKIX parameter set OID %q for an unsupported curve %q: %w", oid, entry.Curve, err)
}
curves = append(curves, curve)
}
}

var configs []endpoint.AllowedKeyConfiguration
if len(rsaSizes) > 0 {
configs = append(configs, endpoint.AllowedKeyConfiguration{KeyType: certificate.KeyTypeRSA, KeySizes: rsaSizes})
}
if len(curves) > 0 {
configs = append(configs, endpoint.AllowedKeyConfiguration{KeyType: certificate.KeyTypeECDSA, KeyCurves: curves})
}
return configs, nil
}

func (sp serverPolicy) toZoneConfig(zc *endpoint.ZoneConfiguration) {
zc.Country = sp.Subject.Country.Value
zc.Organization = sp.Subject.Organization.Value
Expand Down Expand Up @@ -981,7 +1024,13 @@ func (sp serverPolicy) toPolicy() (p endpoint.Policy) {
} else {
p.UpnSanRegExs = []string{}
}
if sp.KeyPair.KeyAlgorithm.Locked {
if sp.KeyPair.PkixParameterSet.Locked && len(sp.KeyPair.PkixParameterSet.Values) > 0 {
configs, err := allowedKeyConfigurationsFromPkixParameterSet(sp.KeyPair.PkixParameterSet.Values)
if err != nil {
panic(err)
}
p.AllowedKeyConfigurations = append(p.AllowedKeyConfigurations, configs...)
} else if sp.KeyPair.KeyAlgorithm.Locked {
var keyType certificate.KeyType
if err := keyType.Set(sp.KeyPair.KeyAlgorithm.Value, sp.KeyPair.EllipticCurve.Value); err != nil {
panic(err)
Expand Down
Loading