Skip to content

Commit

Permalink
update codegen
Browse files Browse the repository at this point in the history
Signed-off-by: cpanato <ctadeu@gmail.com>
  • Loading branch information
cpanato committed Jun 12, 2022
1 parent f4f9b6e commit a992d57
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -446,18 +446,30 @@ func ParsePublicKeyPEM(data []byte) (interface{}, error) {
return nil, errors.New("data does not contain any valid public keys")
}

// addPolicyIdentifiers adds certificate policies extension
//
// AddPolicyIdentifiers adds certificate policies extension, based on CreationBundle
func AddPolicyIdentifiers(data *CreationBundle, certTemplate *x509.Certificate) {
for _, oidstr := range data.Params.PolicyIdentifiers {
oid, err := StringToOid(oidstr)
oidOnly := true
for _, oidStr := range data.Params.PolicyIdentifiers {
oid, err := StringToOid(oidStr)
if err == nil {
certTemplate.PolicyIdentifiers = append(certTemplate.PolicyIdentifiers, oid)
}
if err != nil {
oidOnly = false
}
}
if !oidOnly { // Because all policy information is held in the same extension, when we use an extra extension to
// add policy qualifier information, that overwrites any information in the PolicyIdentifiers field on the Cert
// Template, so we need to reparse all the policy identifiers here
extension, err := CreatePolicyInformationExtensionFromStorageStrings(data.Params.PolicyIdentifiers)
if err == nil {
// If this errors out, don't add it, rely on the OIDs parsed into PolicyIdentifiers above
certTemplate.ExtraExtensions = append(certTemplate.ExtraExtensions, *extension)
}
}
}

// addExtKeyUsageOids adds custom extended key usage OIDs to certificate
// AddExtKeyUsageOids adds custom extended key usage OIDs to certificate
func AddExtKeyUsageOids(data *CreationBundle, certTemplate *x509.Certificate) {
for _, oidstr := range data.Params.ExtKeyUsageOIDs {
oid, err := StringToOid(oidstr)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ import (
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"math/big"
"net"
Expand Down Expand Up @@ -894,3 +897,114 @@ func (p *KeyBundle) ToPrivateKeyPemString() (string, error) {

return "", errutil.InternalError{Err: "No Private Key Bytes to Wrap"}
}

// PolicyIdentifierWithQualifierEntry Structure for Internal Storage
type PolicyIdentifierWithQualifierEntry struct {
PolicyIdentifierOid string `json:"oid",mapstructure:"oid"`
CPS string `json:"cps,omitempty",mapstructure:"cps"`
Notice string `json:"notice,omitempty",mapstructure:"notice"`
}

// GetPolicyIdentifierFromString parses out the internal structure of a Policy Identifier
func GetPolicyIdentifierFromString(policyIdentifier string) (*PolicyIdentifierWithQualifierEntry, error) {
if policyIdentifier == "" {
return nil, nil
}
entry := &PolicyIdentifierWithQualifierEntry{}
// Either a OID, or a JSON Entry: First check OID:
_, err := StringToOid(policyIdentifier)
if err == nil {
entry.PolicyIdentifierOid = policyIdentifier
return entry, nil
}
// Now Check If JSON Entry
jsonErr := json.Unmarshal([]byte(policyIdentifier), &entry)
if jsonErr != nil { // Neither, if we got here
return entry, errors.New(fmt.Sprintf("Policy Identifier %q is neither a valid OID: %s, Nor JSON Policy Identifier: %s", policyIdentifier, err.Error(), jsonErr.Error()))
}
return entry, nil
}

// Policy Identifier with Qualifier Structure for ASN Marshalling:

var policyInformationOid = asn1.ObjectIdentifier{2, 5, 29, 32}

type policyInformation struct {
PolicyIdentifier asn1.ObjectIdentifier
Qualifiers []interface{} `asn1:"tag:optional,omitempty"`
}

var cpsPolicyQualifierID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 1}

type cpsUrlPolicyQualifier struct {
PolicyQualifierID asn1.ObjectIdentifier
Qualifier string `asn1:"tag:optional,ia5"`
}

var userNoticePolicyQualifierID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 2}

type userNoticePolicyQualifier struct {
PolicyQualifierID asn1.ObjectIdentifier
Qualifier userNotice
}

type userNotice struct {
ExplicitText string `asn1:"tag:optional,utf8"`
}

func createPolicyIdentifierWithQualifier(entry PolicyIdentifierWithQualifierEntry) (*policyInformation, error) {
// Each Policy is Identified by a Unique ID, as designated here:
policyOid, err := StringToOid(entry.PolicyIdentifierOid)
if err != nil {
return nil, err
}
pi := policyInformation{
PolicyIdentifier: policyOid,
}
if entry.CPS != "" {
qualifier := cpsUrlPolicyQualifier{
PolicyQualifierID: cpsPolicyQualifierID,
Qualifier: entry.CPS,
}
pi.Qualifiers = append(pi.Qualifiers, qualifier)
}
if entry.Notice != "" {
qualifier := userNoticePolicyQualifier{
PolicyQualifierID: userNoticePolicyQualifierID,
Qualifier: userNotice{
ExplicitText: entry.Notice,
},
}
pi.Qualifiers = append(pi.Qualifiers, qualifier)
}
return &pi, nil
}

// CreatePolicyInformationExtensionFromStorageStrings parses the stored policyIdentifiers, which might be JSON Policy
// Identifier with Qualifier Entries or String OIDs, and returns an extension if everything parsed correctly, and an
// error if constructing
func CreatePolicyInformationExtensionFromStorageStrings(policyIdentifiers []string) (*pkix.Extension, error) {
var policyInformationList []policyInformation
for _, policyIdentifierStr := range policyIdentifiers {
policyIdentifierEntry, err := GetPolicyIdentifierFromString(policyIdentifierStr)
if err != nil {
return nil, err
}
if policyIdentifierEntry != nil { // Okay to skip empty entries if there is no error
policyInformationStruct, err := createPolicyIdentifierWithQualifier(*policyIdentifierEntry)
if err != nil {
return nil, err
}
policyInformationList = append(policyInformationList, *policyInformationStruct)
}
}
asn1Bytes, err := asn1.Marshal(policyInformationList)
if err != nil {
return nil, err
}
return &pkix.Extension{
Id: policyInformationOid,
Critical: false,
Value: asn1Bytes,
}, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var (
// Whether cgo is enabled or not; set at build time
CgoEnabled bool

Version = "1.11.0"
Version = "1.12.0"
VersionPrerelease = "dev1"
VersionMetadata = ""
)

0 comments on commit a992d57

Please sign in to comment.