pem.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package cert
  2. import (
  3. "encoding/pem"
  4. "fmt"
  5. "golang.org/x/crypto/ed25519"
  6. )
  7. const (
  8. CertificateBanner = "NEBULA CERTIFICATE"
  9. CertificateV2Banner = "NEBULA CERTIFICATE V2"
  10. X25519PrivateKeyBanner = "NEBULA X25519 PRIVATE KEY"
  11. X25519PublicKeyBanner = "NEBULA X25519 PUBLIC KEY"
  12. EncryptedEd25519PrivateKeyBanner = "NEBULA ED25519 ENCRYPTED PRIVATE KEY"
  13. Ed25519PrivateKeyBanner = "NEBULA ED25519 PRIVATE KEY"
  14. Ed25519PublicKeyBanner = "NEBULA ED25519 PUBLIC KEY"
  15. P256PrivateKeyBanner = "NEBULA P256 PRIVATE KEY"
  16. P256PublicKeyBanner = "NEBULA P256 PUBLIC KEY"
  17. EncryptedECDSAP256PrivateKeyBanner = "NEBULA ECDSA P256 ENCRYPTED PRIVATE KEY"
  18. ECDSAP256PrivateKeyBanner = "NEBULA ECDSA P256 PRIVATE KEY"
  19. )
  20. // UnmarshalCertificateFromPEM will try to unmarshal the first pem block in a byte array, returning any non consumed
  21. // data or an error on failure
  22. func UnmarshalCertificateFromPEM(b []byte) (Certificate, []byte, error) {
  23. p, r := pem.Decode(b)
  24. if p == nil {
  25. return nil, r, ErrInvalidPEMBlock
  26. }
  27. switch p.Type {
  28. case CertificateBanner:
  29. c, err := unmarshalCertificateV1(p.Bytes, true)
  30. if err != nil {
  31. return nil, nil, err
  32. }
  33. return c, r, nil
  34. case CertificateV2Banner:
  35. //TODO
  36. panic("TODO")
  37. default:
  38. return nil, r, ErrInvalidPEMCertificateBanner
  39. }
  40. }
  41. func MarshalPublicKeyToPEM(curve Curve, b []byte) []byte {
  42. switch curve {
  43. case Curve_CURVE25519:
  44. return pem.EncodeToMemory(&pem.Block{Type: X25519PublicKeyBanner, Bytes: b})
  45. case Curve_P256:
  46. return pem.EncodeToMemory(&pem.Block{Type: P256PublicKeyBanner, Bytes: b})
  47. default:
  48. return nil
  49. }
  50. }
  51. func UnmarshalPublicKeyFromPEM(b []byte) ([]byte, []byte, Curve, error) {
  52. k, r := pem.Decode(b)
  53. if k == nil {
  54. return nil, r, 0, fmt.Errorf("input did not contain a valid PEM encoded block")
  55. }
  56. var expectedLen int
  57. var curve Curve
  58. switch k.Type {
  59. case X25519PublicKeyBanner, Ed25519PublicKeyBanner:
  60. expectedLen = 32
  61. curve = Curve_CURVE25519
  62. case P256PublicKeyBanner:
  63. // Uncompressed
  64. expectedLen = 65
  65. curve = Curve_P256
  66. default:
  67. return nil, r, 0, fmt.Errorf("bytes did not contain a proper public key banner")
  68. }
  69. if len(k.Bytes) != expectedLen {
  70. return nil, r, 0, fmt.Errorf("key was not %d bytes, is invalid %s public key", expectedLen, curve)
  71. }
  72. return k.Bytes, r, curve, nil
  73. }
  74. func MarshalPrivateKeyToPEM(curve Curve, b []byte) []byte {
  75. switch curve {
  76. case Curve_CURVE25519:
  77. return pem.EncodeToMemory(&pem.Block{Type: X25519PrivateKeyBanner, Bytes: b})
  78. case Curve_P256:
  79. return pem.EncodeToMemory(&pem.Block{Type: P256PrivateKeyBanner, Bytes: b})
  80. default:
  81. return nil
  82. }
  83. }
  84. func MarshalSigningPrivateKeyToPEM(curve Curve, b []byte) []byte {
  85. switch curve {
  86. case Curve_CURVE25519:
  87. return pem.EncodeToMemory(&pem.Block{Type: Ed25519PrivateKeyBanner, Bytes: b})
  88. case Curve_P256:
  89. return pem.EncodeToMemory(&pem.Block{Type: ECDSAP256PrivateKeyBanner, Bytes: b})
  90. default:
  91. return nil
  92. }
  93. }
  94. // UnmarshalPrivateKeyFromPEM will try to unmarshal the first pem block in a byte array, returning any non
  95. // consumed data or an error on failure
  96. func UnmarshalPrivateKeyFromPEM(b []byte) ([]byte, []byte, Curve, error) {
  97. k, r := pem.Decode(b)
  98. if k == nil {
  99. return nil, r, 0, fmt.Errorf("input did not contain a valid PEM encoded block")
  100. }
  101. var expectedLen int
  102. var curve Curve
  103. switch k.Type {
  104. case X25519PrivateKeyBanner:
  105. expectedLen = 32
  106. curve = Curve_CURVE25519
  107. case P256PrivateKeyBanner:
  108. expectedLen = 32
  109. curve = Curve_P256
  110. default:
  111. return nil, r, 0, fmt.Errorf("bytes did not contain a proper private key banner")
  112. }
  113. if len(k.Bytes) != expectedLen {
  114. return nil, r, 0, fmt.Errorf("key was not %d bytes, is invalid %s private key", expectedLen, curve)
  115. }
  116. return k.Bytes, r, curve, nil
  117. }
  118. func UnmarshalSigningPrivateKeyFromPEM(b []byte) ([]byte, []byte, Curve, error) {
  119. k, r := pem.Decode(b)
  120. if k == nil {
  121. return nil, r, 0, fmt.Errorf("input did not contain a valid PEM encoded block")
  122. }
  123. var curve Curve
  124. switch k.Type {
  125. case EncryptedEd25519PrivateKeyBanner:
  126. return nil, nil, Curve_CURVE25519, ErrPrivateKeyEncrypted
  127. case EncryptedECDSAP256PrivateKeyBanner:
  128. return nil, nil, Curve_P256, ErrPrivateKeyEncrypted
  129. case Ed25519PrivateKeyBanner:
  130. curve = Curve_CURVE25519
  131. if len(k.Bytes) != ed25519.PrivateKeySize {
  132. return nil, r, 0, fmt.Errorf("key was not %d bytes, is invalid Ed25519 private key", ed25519.PrivateKeySize)
  133. }
  134. case ECDSAP256PrivateKeyBanner:
  135. curve = Curve_P256
  136. if len(k.Bytes) != 32 {
  137. return nil, r, 0, fmt.Errorf("key was not 32 bytes, is invalid ECDSA P256 private key")
  138. }
  139. default:
  140. return nil, r, 0, fmt.Errorf("bytes did not contain a proper Ed25519/ECDSA private key banner")
  141. }
  142. return k.Bytes, r, curve, nil
  143. }