...

Source file src/github.com/Microsoft/hcsshim/internal/cosesign1/makedidx509.go

Documentation: github.com/Microsoft/hcsshim/internal/cosesign1

     1  package cosesign1
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"crypto/x509"
     6  	"encoding/base64"
     7  	"encoding/pem"
     8  	"errors"
     9  	"fmt"
    10  	"net/url"
    11  	"strings"
    12  
    13  	didx509resolver "github.com/Microsoft/hcsshim/internal/did-x509-resolver"
    14  	"github.com/sirupsen/logrus"
    15  )
    16  
    17  func parsePemChain(chainPem string) ([]*x509.Certificate, error) {
    18  	var chain = []*x509.Certificate{}
    19  
    20  	bs := []byte(chainPem)
    21  	for block, rest := pem.Decode(bs); block != nil; block, rest = pem.Decode(rest) {
    22  		if block.Type == "CERTIFICATE" {
    23  			cert, err := x509.ParseCertificate(block.Bytes)
    24  			if err != nil {
    25  				return nil, fmt.Errorf("certificate parser failed: %w", err)
    26  			}
    27  			chain = append(chain, cert)
    28  		}
    29  	}
    30  
    31  	return chain, nil
    32  }
    33  
    34  func MakeDidX509(fingerprintAlgorithm string, fingerprintIndex int, chainPEM string, didPolicy string, verbose bool) (string, error) {
    35  	if fingerprintAlgorithm != "sha256" {
    36  		return "", fmt.Errorf("unsupported fingerprint hash algorithm %q", fingerprintAlgorithm)
    37  	}
    38  
    39  	if fingerprintIndex < 1 {
    40  		return "", fmt.Errorf("fingerprint index must be >= 1")
    41  	}
    42  
    43  	chain, err := parsePemChain(chainPEM)
    44  	if err != nil {
    45  		return "", err
    46  	}
    47  
    48  	if len(chain) < 1 {
    49  		return "", fmt.Errorf("chain must not be empty")
    50  	}
    51  
    52  	if fingerprintIndex > len(chain)-1 {
    53  		return "", fmt.Errorf("signer index out of bounds")
    54  	}
    55  
    56  	signerCert := chain[fingerprintIndex]
    57  	hash := sha256.Sum256(signerCert.Raw)
    58  	fingerprint := base64.RawURLEncoding.EncodeToString(hash[:])
    59  
    60  	var policyTokens []string
    61  	didPolicyUpper := strings.ToUpper(didPolicy)
    62  	switch didPolicyUpper {
    63  	case "CN":
    64  		policyTokens = append(policyTokens, "subject", "CN", chain[0].Subject.CommonName)
    65  	case "EKU":
    66  		// Note: In general there may be many predefined and not predefined key usages.
    67  		// We pick the first non-predefined one, or, if there are none, the first predefined one.
    68  		// Others must be specified manually (as in custom, next branch).
    69  
    70  		// non-predefined
    71  		if len(chain[0].UnknownExtKeyUsage) > 0 {
    72  			policyTokens = append(policyTokens, "eku", chain[0].UnknownExtKeyUsage[0].String())
    73  		} else if len(chain[0].ExtKeyUsage) > 0 {
    74  			extendedKeyUsage := chain[0].ExtKeyUsage[0]
    75  			keyUsageOid, ok := didx509resolver.OidFromExtKeyUsage(extendedKeyUsage)
    76  			// predefined
    77  			if ok {
    78  				policyTokens = append(policyTokens, "eku", keyUsageOid.String())
    79  			}
    80  		}
    81  	default:
    82  		// Custom policies
    83  		policyTokens = strings.Split(didPolicy, ":")
    84  	}
    85  
    86  	if len(policyTokens) == 0 {
    87  		return "", errors.New("invalid policy")
    88  	}
    89  
    90  	for i := 0; i < len(policyTokens); i++ {
    91  		policyName := policyTokens[i]
    92  		switch policyName {
    93  		case "subject":
    94  			i += 2
    95  			if i >= len(policyTokens) {
    96  				return "", fmt.Errorf("invalid %q policy", policyName)
    97  			}
    98  			policyTokens[i] = url.PathEscape(policyTokens[i])
    99  		default:
   100  		}
   101  	}
   102  
   103  	r := "did:x509:0:" + fingerprintAlgorithm + ":" + fingerprint + "::" + strings.Join(policyTokens, ":")
   104  	_, err = didx509resolver.Resolve(chainPEM, r, true)
   105  	if err != nil {
   106  		return "", err
   107  	}
   108  
   109  	if verbose {
   110  		logrus.Debug("did:x509 resolved correctly")
   111  	}
   112  
   113  	return r, nil
   114  }
   115  

View as plain text