pkcs8.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package x509
  5. import (
  6. "crypto/ecdsa"
  7. "crypto/rsa"
  8. "errors"
  9. "fmt"
  10. "github.com/google/certificate-transparency-go/asn1"
  11. "github.com/google/certificate-transparency-go/x509/pkix"
  12. // TODO(robpercival): change this to crypto/ed25519 when Go 1.13 is min version
  13. "golang.org/x/crypto/ed25519"
  14. )
  15. // pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See
  16. // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn
  17. // and RFC 5208.
  18. type pkcs8 struct {
  19. Version int
  20. Algo pkix.AlgorithmIdentifier
  21. PrivateKey []byte
  22. // optional attributes omitted.
  23. }
  24. // ParsePKCS8PrivateKey parses an unencrypted private key in PKCS#8, ASN.1 DER form.
  25. //
  26. // It returns a *rsa.PrivateKey, a *ecdsa.PrivateKey, or a ed25519.PrivateKey.
  27. // More types might be supported in the future.
  28. //
  29. // This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY".
  30. func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
  31. var privKey pkcs8
  32. if _, err := asn1.Unmarshal(der, &privKey); err != nil {
  33. if _, err := asn1.Unmarshal(der, &ecPrivateKey{}); err == nil {
  34. return nil, errors.New("x509: failed to parse private key (use ParseECPrivateKey instead for this key format)")
  35. }
  36. if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil {
  37. return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
  38. }
  39. return nil, err
  40. }
  41. switch {
  42. case privKey.Algo.Algorithm.Equal(OIDPublicKeyRSA):
  43. key, err = ParsePKCS1PrivateKey(privKey.PrivateKey)
  44. if err != nil {
  45. return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error())
  46. }
  47. return key, nil
  48. case privKey.Algo.Algorithm.Equal(OIDPublicKeyECDSA):
  49. bytes := privKey.Algo.Parameters.FullBytes
  50. namedCurveOID := new(asn1.ObjectIdentifier)
  51. if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil {
  52. namedCurveOID = nil
  53. }
  54. key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey)
  55. if err != nil {
  56. return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error())
  57. }
  58. return key, nil
  59. case privKey.Algo.Algorithm.Equal(OIDPublicKeyEd25519):
  60. if l := len(privKey.Algo.Parameters.FullBytes); l != 0 {
  61. return nil, errors.New("x509: invalid Ed25519 private key parameters")
  62. }
  63. var curvePrivateKey []byte
  64. if _, err := asn1.Unmarshal(privKey.PrivateKey, &curvePrivateKey); err != nil {
  65. return nil, fmt.Errorf("x509: invalid Ed25519 private key: %v", err)
  66. }
  67. if l := len(curvePrivateKey); l != ed25519.SeedSize {
  68. return nil, fmt.Errorf("x509: invalid Ed25519 private key length: %d", l)
  69. }
  70. return ed25519.NewKeyFromSeed(curvePrivateKey), nil
  71. default:
  72. return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm)
  73. }
  74. }
  75. // MarshalPKCS8PrivateKey converts a private key to PKCS#8, ASN.1 DER form.
  76. //
  77. // The following key types are currently supported: *rsa.PrivateKey, *ecdsa.PrivateKey
  78. // and ed25519.PrivateKey. Unsupported key types result in an error.
  79. //
  80. // This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY".
  81. func MarshalPKCS8PrivateKey(key interface{}) ([]byte, error) {
  82. var privKey pkcs8
  83. switch k := key.(type) {
  84. case *rsa.PrivateKey:
  85. privKey.Algo = pkix.AlgorithmIdentifier{
  86. Algorithm: OIDPublicKeyRSA,
  87. Parameters: asn1.NullRawValue,
  88. }
  89. privKey.PrivateKey = MarshalPKCS1PrivateKey(k)
  90. case *ecdsa.PrivateKey:
  91. oid, ok := OIDFromNamedCurve(k.Curve)
  92. if !ok {
  93. return nil, errors.New("x509: unknown curve while marshaling to PKCS#8")
  94. }
  95. oidBytes, err := asn1.Marshal(oid)
  96. if err != nil {
  97. return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
  98. }
  99. privKey.Algo = pkix.AlgorithmIdentifier{
  100. Algorithm: OIDPublicKeyECDSA,
  101. Parameters: asn1.RawValue{
  102. FullBytes: oidBytes,
  103. },
  104. }
  105. if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil {
  106. return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
  107. }
  108. case ed25519.PrivateKey:
  109. privKey.Algo = pkix.AlgorithmIdentifier{
  110. Algorithm: OIDPublicKeyEd25519,
  111. }
  112. curvePrivateKey, err := asn1.Marshal(k.Seed())
  113. if err != nil {
  114. return nil, fmt.Errorf("x509: failed to marshal private key: %v", err)
  115. }
  116. privKey.PrivateKey = curvePrivateKey
  117. default:
  118. return nil, fmt.Errorf("x509: unknown key type while marshaling PKCS#8: %T", key)
  119. }
  120. return asn1.Marshal(privKey)
  121. }