key_provider.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. // Package kp describes transport key providers and provides a reference
  2. // implementation.
  3. //
  4. // KeyProviders are used by clients and servers as a mechanism for
  5. // providing keys and signing CSRs. It is a mechanism designed to
  6. // allow switching out how private keys and their associated
  7. // certificates are managed, such as supporting PKCS #11. The
  8. // StandardProvider provides disk-backed PEM-encoded certificates and
  9. // private keys. DiskFallback is a provider that will attempt to
  10. // retrieve the certificate from a CA first, falling back to a
  11. // disk-backed pair. This is useful for test a CA while providing a
  12. // failover solution.
  13. package kp
  14. import (
  15. "crypto"
  16. "crypto/ecdsa"
  17. "crypto/ed25519"
  18. "crypto/elliptic"
  19. "crypto/rand"
  20. "crypto/rsa"
  21. "crypto/tls"
  22. "crypto/x509"
  23. "encoding/pem"
  24. "errors"
  25. "io"
  26. "os"
  27. "strings"
  28. "github.com/cloudflare/cfssl/csr"
  29. "github.com/cloudflare/cfssl/helpers"
  30. "github.com/cloudflare/cfssl/helpers/derhelpers"
  31. "github.com/cloudflare/cfssl/transport/core"
  32. )
  33. const (
  34. curveP256 = 256
  35. curveP384 = 384
  36. curveP521 = 521
  37. )
  38. // A KeyProvider provides some mechanism for managing private keys and
  39. // certificates. It is not required to store the crypto.Signer itself.
  40. type KeyProvider interface {
  41. // Certificate returns the associated certificate, or nil if
  42. // one isn't ready.
  43. Certificate() *x509.Certificate
  44. // Given some metadata about a certificate request, the
  45. // provider should be able to generate a new CSR.
  46. CertificateRequest(*csr.CertificateRequest) ([]byte, error)
  47. // Check returns an error if the provider has an invalid setup.
  48. Check() error
  49. // Generate should trigger the creation of a new private
  50. // key. This will invalidate any certificates stored in the
  51. // key provider.
  52. Generate(algo string, size int) error
  53. // Load causes a private key and certificate associated with
  54. // this provider to be loaded into memory and be prepared for
  55. // use.
  56. Load() error
  57. // Persistent returns true if the provider keeps state on disk.
  58. Persistent() bool
  59. // Ready returns true if the provider has a key and
  60. // certificate.
  61. Ready() bool
  62. // SetCertificatePEM takes a PEM-encoded certificate and
  63. // associates it with this key provider.
  64. SetCertificatePEM([]byte) error
  65. // SignalFailure is used to notify the KeyProvider that an
  66. // error has occurred obtaining a certificate. If this returns
  67. // true, the caller should re-attempt to refresh the
  68. // keys. This, for example, can be used to implement failover
  69. // key providers that require different keys.
  70. SignalFailure(err error) bool
  71. // SignCSR allows a templated CSR to be signed.
  72. SignCSR(csr *x509.CertificateRequest) ([]byte, error)
  73. // Store should perform whatever actions are necessary such
  74. // that a call to Load later will reload the key and
  75. // certificate associated with this provider.
  76. Store() error
  77. // X509KeyPair returns a tls.Certficate. The returns
  78. // tls.Certificate should have a parsed Leaf certificate.
  79. X509KeyPair() (tls.Certificate, error)
  80. }
  81. // StandardPaths contains a path to a key file and certificate file.
  82. type StandardPaths struct {
  83. KeyFile string `json:"private_key"`
  84. CertFile string `json:"certificate"`
  85. }
  86. // StandardProvider provides unencrypted PEM-encoded certificates and
  87. // private keys. If paths are provided, the key and certificate will
  88. // be stored on disk.
  89. type StandardProvider struct {
  90. Paths StandardPaths `json:"paths"`
  91. internal struct {
  92. priv crypto.Signer
  93. cert *x509.Certificate
  94. // The PEM-encoded private key and certificate. This
  95. // is stored alongside the crypto.Signer and
  96. // x509.Certificate for convenience in marshaling and
  97. // calling tls.X509KeyPair directly.
  98. keyPEM []byte
  99. certPEM []byte
  100. }
  101. }
  102. // NewStandardProvider sets up new StandardProvider from the
  103. // information contained in an Identity.
  104. func NewStandardProvider(id *core.Identity) (*StandardProvider, error) {
  105. if id == nil {
  106. return nil, errors.New("transport: the identity hasn't been initialised. Has it been loaded from disk?")
  107. }
  108. paths := id.Profiles["paths"]
  109. if paths == nil {
  110. return &StandardProvider{}, nil
  111. }
  112. sp := &StandardProvider{
  113. Paths: StandardPaths{
  114. KeyFile: paths["private_key"],
  115. CertFile: paths["certificate"],
  116. },
  117. }
  118. err := sp.Check()
  119. if err != nil {
  120. return nil, err
  121. }
  122. return sp, nil
  123. }
  124. func (sp *StandardProvider) resetCert() {
  125. sp.internal.cert = nil
  126. sp.internal.certPEM = nil
  127. }
  128. func (sp *StandardProvider) resetKey() {
  129. sp.internal.priv = nil
  130. sp.internal.keyPEM = nil
  131. }
  132. var (
  133. // ErrMissingKeyPath is returned if the StandardProvider has
  134. // specified a certificate path but not a key path.
  135. ErrMissingKeyPath = errors.New("transport: standard provider is missing a private key path to accompany the certificate path")
  136. // ErrMissingCertPath is returned if the StandardProvider has
  137. // specified a private key path but not a certificate path.
  138. ErrMissingCertPath = errors.New("transport: standard provider is missing a certificate path to accompany the certificate path")
  139. )
  140. // Check ensures that the paths are valid for the provider.
  141. func (sp *StandardProvider) Check() error {
  142. if sp.Paths.KeyFile == "" && sp.Paths.CertFile == "" {
  143. return nil
  144. }
  145. if sp.Paths.KeyFile == "" {
  146. return ErrMissingKeyPath
  147. }
  148. if sp.Paths.CertFile == "" {
  149. return ErrMissingCertPath
  150. }
  151. return nil
  152. }
  153. // Persistent returns true if the key and certificate will be stored
  154. // on disk.
  155. func (sp *StandardProvider) Persistent() bool {
  156. return sp.Paths.KeyFile != "" && sp.Paths.CertFile != ""
  157. }
  158. // Generate generates a new private key.
  159. func (sp *StandardProvider) Generate(algo string, size int) (err error) {
  160. sp.resetKey()
  161. sp.resetCert()
  162. algo = strings.ToLower(algo)
  163. switch algo {
  164. case "rsa":
  165. var priv *rsa.PrivateKey
  166. if size < 2048 {
  167. return errors.New("transport: RSA keys must be at least 2048 bits")
  168. }
  169. priv, err = rsa.GenerateKey(rand.Reader, size)
  170. if err != nil {
  171. return err
  172. }
  173. keyPEM := x509.MarshalPKCS1PrivateKey(priv)
  174. p := &pem.Block{
  175. Type: "RSA PRIVATE KEY",
  176. Bytes: keyPEM,
  177. }
  178. sp.internal.keyPEM = pem.EncodeToMemory(p)
  179. sp.internal.priv = priv
  180. case "ecdsa":
  181. var priv *ecdsa.PrivateKey
  182. var curve elliptic.Curve
  183. switch size {
  184. case curveP256:
  185. curve = elliptic.P256()
  186. case curveP384:
  187. curve = elliptic.P384()
  188. case curveP521:
  189. curve = elliptic.P521()
  190. default:
  191. return errors.New("transport: invalid elliptic curve key size; only 256-, 384-, and 521-bit keys are accepted")
  192. }
  193. priv, err = ecdsa.GenerateKey(curve, rand.Reader)
  194. if err != nil {
  195. return err
  196. }
  197. var keyPEM []byte
  198. keyPEM, err = x509.MarshalECPrivateKey(priv)
  199. if err != nil {
  200. return err
  201. }
  202. p := &pem.Block{
  203. Type: "EC PRIVATE KEY",
  204. Bytes: keyPEM,
  205. }
  206. sp.internal.keyPEM = pem.EncodeToMemory(p)
  207. sp.internal.priv = priv
  208. case "ed25519":
  209. seed := make([]byte, ed25519.SeedSize)
  210. if _, err := io.ReadFull(rand.Reader, seed); err != nil {
  211. return err
  212. }
  213. priv := ed25519.NewKeyFromSeed(seed)
  214. keyPEM, err := derhelpers.MarshalEd25519PrivateKey(priv)
  215. if err != nil {
  216. return err
  217. }
  218. p := &pem.Block{
  219. Type: "Ed25519 PRIVATE KEY",
  220. Bytes: keyPEM,
  221. }
  222. sp.internal.keyPEM = pem.EncodeToMemory(p)
  223. sp.internal.priv = priv
  224. default:
  225. return errors.New("transport: invalid key algorithm; only RSA, Ed25519 and ECDSA are supported")
  226. }
  227. return nil
  228. }
  229. // Certificate returns the associated certificate, or nil if
  230. // one isn't ready.
  231. func (sp *StandardProvider) Certificate() *x509.Certificate {
  232. return sp.internal.cert
  233. }
  234. // CertificateRequest takes some metadata about a certificate request,
  235. // and attempts to produce a certificate signing request suitable for
  236. // sending to a certificate authority.
  237. func (sp *StandardProvider) CertificateRequest(req *csr.CertificateRequest) ([]byte, error) {
  238. if sp.internal.priv == nil {
  239. if req.KeyRequest == nil {
  240. return nil, errors.New("transport: invalid key request in csr.CertificateRequest")
  241. }
  242. sp.Generate(req.KeyRequest.Algo(), req.KeyRequest.Size())
  243. }
  244. return csr.Generate(sp.internal.priv, req)
  245. }
  246. // ErrCertificateUnavailable is returned when a key is available, but
  247. // there is no accompanying certificate.
  248. var ErrCertificateUnavailable = errors.New("transport: certificate unavailable")
  249. // Load a private key and certificate from disk.
  250. func (sp *StandardProvider) Load() (err error) {
  251. if !sp.Persistent() {
  252. return
  253. }
  254. var clearKey = true
  255. defer func() {
  256. if err != nil {
  257. if clearKey {
  258. sp.resetKey()
  259. }
  260. sp.resetCert()
  261. }
  262. }()
  263. sp.internal.keyPEM, err = os.ReadFile(sp.Paths.KeyFile)
  264. if err != nil {
  265. return
  266. }
  267. sp.internal.priv, err = helpers.ParsePrivateKeyPEM(sp.internal.keyPEM)
  268. if err != nil {
  269. return
  270. }
  271. clearKey = false
  272. sp.internal.certPEM, err = os.ReadFile(sp.Paths.CertFile)
  273. if err != nil {
  274. return ErrCertificateUnavailable
  275. }
  276. sp.internal.cert, err = helpers.ParseCertificatePEM(sp.internal.certPEM)
  277. if err != nil {
  278. err = errors.New("transport: invalid certificate")
  279. return
  280. }
  281. p, _ := pem.Decode(sp.internal.keyPEM)
  282. switch sp.internal.cert.PublicKey.(type) {
  283. case *rsa.PublicKey:
  284. if p.Type != "RSA PRIVATE KEY" {
  285. err = errors.New("transport: PEM type " + p.Type + " is invalid for an RSA key")
  286. return
  287. }
  288. case *ecdsa.PublicKey:
  289. if p.Type != "EC PRIVATE KEY" {
  290. err = errors.New("transport: PEM type " + p.Type + " is invalid for an ECDSA key")
  291. return
  292. }
  293. case ed25519.PublicKey:
  294. if p.Type != "Ed25519 PRIVATE KEY" {
  295. err = errors.New("transport: PEM type" + p.Type + "is invalid for an Ed25519 key")
  296. return
  297. }
  298. default:
  299. err = errors.New("transport: invalid public key type")
  300. }
  301. if err != nil {
  302. clearKey = true
  303. return
  304. }
  305. return nil
  306. }
  307. // Ready returns true if the provider has a key and certificate
  308. // loaded. The certificate should be checked by the end user for
  309. // validity.
  310. func (sp *StandardProvider) Ready() bool {
  311. switch {
  312. case sp.internal.priv == nil:
  313. return false
  314. case sp.internal.cert == nil:
  315. return false
  316. case sp.internal.keyPEM == nil:
  317. return false
  318. case sp.internal.certPEM == nil:
  319. return false
  320. default:
  321. return true
  322. }
  323. }
  324. // SetCertificatePEM receives a PEM-encoded certificate and loads it
  325. // into the provider.
  326. func (sp *StandardProvider) SetCertificatePEM(certPEM []byte) error {
  327. cert, err := helpers.ParseCertificatePEM(certPEM)
  328. if err != nil {
  329. return errors.New("transport: invalid certificate")
  330. }
  331. sp.internal.certPEM = certPEM
  332. sp.internal.cert = cert
  333. return nil
  334. }
  335. // SignalFailure is provided to implement the KeyProvider interface,
  336. // and always returns false.
  337. func (sp *StandardProvider) SignalFailure(err error) bool {
  338. return false
  339. }
  340. // SignCSR takes a template certificate request and signs it.
  341. func (sp *StandardProvider) SignCSR(tpl *x509.CertificateRequest) ([]byte, error) {
  342. return x509.CreateCertificateRequest(rand.Reader, tpl, sp.internal.priv)
  343. }
  344. // Store writes the key and certificate to disk, if necessary.
  345. func (sp *StandardProvider) Store() error {
  346. if !sp.Ready() {
  347. return errors.New("transport: provider does not have a key and certificate")
  348. }
  349. err := os.WriteFile(sp.Paths.CertFile, sp.internal.certPEM, 0644)
  350. if err != nil {
  351. return err
  352. }
  353. return os.WriteFile(sp.Paths.KeyFile, sp.internal.keyPEM, 0600)
  354. }
  355. // X509KeyPair returns a tls.Certificate for the provider.
  356. func (sp *StandardProvider) X509KeyPair() (tls.Certificate, error) {
  357. cert, err := tls.X509KeyPair(sp.internal.certPEM, sp.internal.keyPEM)
  358. if err != nil {
  359. return tls.Certificate{}, err
  360. }
  361. if cert.Leaf == nil {
  362. cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
  363. if err != nil {
  364. return tls.Certificate{}, err
  365. }
  366. }
  367. return cert, nil
  368. }