certificates.go 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. package ca
  2. import (
  3. "bytes"
  4. "crypto"
  5. "crypto/ecdsa"
  6. "crypto/elliptic"
  7. cryptorand "crypto/rand"
  8. "crypto/rsa"
  9. "crypto/tls"
  10. "crypto/x509"
  11. "encoding/asn1"
  12. "encoding/pem"
  13. "fmt"
  14. "io"
  15. "io/ioutil"
  16. "os"
  17. "path/filepath"
  18. "time"
  19. cfcsr "github.com/cloudflare/cfssl/csr"
  20. "github.com/cloudflare/cfssl/helpers"
  21. "github.com/cloudflare/cfssl/initca"
  22. cflog "github.com/cloudflare/cfssl/log"
  23. cfsigner "github.com/cloudflare/cfssl/signer"
  24. "github.com/cloudflare/cfssl/signer/local"
  25. "github.com/docker/go-events"
  26. "github.com/docker/swarmkit/api"
  27. "github.com/docker/swarmkit/connectionbroker"
  28. "github.com/docker/swarmkit/ioutils"
  29. "github.com/opencontainers/go-digest"
  30. "github.com/pkg/errors"
  31. "golang.org/x/net/context"
  32. "google.golang.org/grpc"
  33. "google.golang.org/grpc/codes"
  34. "google.golang.org/grpc/credentials"
  35. )
  36. const (
  37. // Security Strength Equivalence
  38. //-----------------------------------
  39. //| ECC | DH/DSA/RSA |
  40. //| 256 | 3072 |
  41. //| 384 | 7680 |
  42. //-----------------------------------
  43. // RootKeySize is the default size of the root CA key
  44. // It would be ideal for the root key to use P-384, but in P-384 is not optimized in go yet :(
  45. RootKeySize = 256
  46. // RootKeyAlgo defines the default algorithm for the root CA Key
  47. RootKeyAlgo = "ecdsa"
  48. // PassphraseENVVar defines the environment variable to look for the
  49. // root CA private key material encryption key
  50. PassphraseENVVar = "SWARM_ROOT_CA_PASSPHRASE"
  51. // PassphraseENVVarPrev defines the alternate environment variable to look for the
  52. // root CA private key material encryption key. It can be used for seamless
  53. // KEK rotations.
  54. PassphraseENVVarPrev = "SWARM_ROOT_CA_PASSPHRASE_PREV"
  55. // RootCAExpiration represents the default expiration for the root CA in seconds (20 years)
  56. RootCAExpiration = "630720000s"
  57. // DefaultNodeCertExpiration represents the default expiration for node certificates (3 months)
  58. DefaultNodeCertExpiration = 2160 * time.Hour
  59. // CertBackdate represents the amount of time each certificate is backdated to try to avoid
  60. // clock drift issues.
  61. CertBackdate = 1 * time.Hour
  62. // CertLowerRotationRange represents the minimum fraction of time that we will wait when randomly
  63. // choosing our next certificate rotation
  64. CertLowerRotationRange = 0.5
  65. // CertUpperRotationRange represents the maximum fraction of time that we will wait when randomly
  66. // choosing our next certificate rotation
  67. CertUpperRotationRange = 0.8
  68. // MinNodeCertExpiration represents the minimum expiration for node certificates
  69. MinNodeCertExpiration = 1 * time.Hour
  70. )
  71. // BasicConstraintsOID is the ASN1 Object ID indicating a basic constraints extension
  72. var BasicConstraintsOID = asn1.ObjectIdentifier{2, 5, 29, 19}
  73. // A recoverableErr is a non-fatal error encountered signing a certificate,
  74. // which means that the certificate issuance may be retried at a later time.
  75. type recoverableErr struct {
  76. err error
  77. }
  78. func (r recoverableErr) Error() string {
  79. return r.err.Error()
  80. }
  81. // ErrNoLocalRootCA is an error type used to indicate that the local root CA
  82. // certificate file does not exist.
  83. var ErrNoLocalRootCA = errors.New("local root CA certificate does not exist")
  84. // ErrNoValidSigner is an error type used to indicate that our RootCA doesn't have the ability to
  85. // sign certificates.
  86. var ErrNoValidSigner = recoverableErr{err: errors.New("no valid signer found")}
  87. func init() {
  88. cflog.Level = 5
  89. }
  90. // CertPaths is a helper struct that keeps track of the paths of a
  91. // Cert and corresponding Key
  92. type CertPaths struct {
  93. Cert, Key string
  94. }
  95. // LocalSigner is a signer that can sign CSRs
  96. type LocalSigner struct {
  97. cfsigner.Signer
  98. // Key will only be used by the original manager to put the private
  99. // key-material in raft, no signing operations depend on it.
  100. Key []byte
  101. // Cert is one PEM encoded Certificate used as the signing CA. It must correspond to the key.
  102. Cert []byte
  103. // just cached parsed values for validation, etc.
  104. parsedCert *x509.Certificate
  105. cryptoSigner crypto.Signer
  106. }
  107. // RootCA is the representation of everything we need to sign certificates and/or to verify certificates
  108. //
  109. // RootCA.Cert: [CA cert1][CA cert2]
  110. // RootCA.Intermediates: [intermediate CA1][intermediate CA2][intermediate CA3]
  111. // RootCA.signer.Cert: [signing CA cert]
  112. // RootCA.signer.Key: [signing CA key]
  113. //
  114. // Requirements:
  115. //
  116. // - [signing CA key] must be the private key for [signing CA cert], and either both or none must be provided
  117. //
  118. // - [intermediate CA1] must have the same public key and subject as [signing CA cert], because otherwise when
  119. // appended to a leaf certificate, the intermediates will not form a chain (because [intermediate CA1] won't because
  120. // the signer of the leaf certificate)
  121. // - [intermediate CA1] must be signed by [intermediate CA2], which must be signed by [intermediate CA3]
  122. //
  123. // - When we issue a certificate, the intermediates will be appended so that the certificate looks like:
  124. // [leaf signed by signing CA cert][intermediate CA1][intermediate CA2][intermediate CA3]
  125. // - [leaf signed by signing CA cert][intermediate CA1][intermediate CA2][intermediate CA3] is guaranteed to form a
  126. // valid chain from [leaf signed by signing CA cert] to one of the root certs ([signing CA cert], [CA cert1], [CA cert2])
  127. // using zero or more of the intermediate certs ([intermediate CA1][intermediate CA2][intermediate CA3]) as intermediates
  128. //
  129. // Example 1: Simple root rotation
  130. // - Initial state:
  131. // - RootCA.Cert: [Root CA1 self-signed]
  132. // - RootCA.Intermediates: []
  133. // - RootCA.signer.Cert: [Root CA1 self-signed]
  134. // - Issued TLS cert: [leaf signed by Root CA1]
  135. //
  136. // - Intermediate state (during root rotation):
  137. // - RootCA.Cert: [Root CA1 self-signed]
  138. // - RootCA.Intermediates: [Root CA2 signed by Root CA1]
  139. // - RootCA.signer.Cert: [Root CA2 signed by Root CA1]
  140. // - Issued TLS cert: [leaf signed by Root CA2][Root CA2 signed by Root CA1]
  141. //
  142. // - Final state:
  143. // - RootCA.Cert: [Root CA2 self-signed]
  144. // - RootCA.Intermediates: []
  145. // - RootCA.signer.Cert: [Root CA2 self-signed]
  146. // - Issued TLS cert: [leaf signed by Root CA2]
  147. //
  148. type RootCA struct {
  149. // Certs contains a bundle of self-signed, PEM encoded certificates for the Root CA to be used
  150. // as the root of trust.
  151. Certs []byte
  152. // Intermediates contains a bundle of PEM encoded intermediate CA certificates to append to any
  153. // issued TLS (leaf) certificates. The first one must have the same public key and subject as the
  154. // signing root certificate, and the rest must form a chain, each one certifying the one above it,
  155. // as per RFC5246 section 7.4.2.
  156. Intermediates []byte
  157. // Pool is the root pool used to validate TLS certificates
  158. Pool *x509.CertPool
  159. // Digest of the serialized bytes of the certificate(s)
  160. Digest digest.Digest
  161. // This signer will be nil if the node doesn't have the appropriate key material
  162. signer *LocalSigner
  163. }
  164. // Signer is an accessor for the local signer that returns an error if this root cannot sign.
  165. func (rca *RootCA) Signer() (*LocalSigner, error) {
  166. if rca.Pool == nil || rca.signer == nil || len(rca.signer.Cert) == 0 || rca.signer.Signer == nil {
  167. return nil, ErrNoValidSigner
  168. }
  169. return rca.signer, nil
  170. }
  171. // IssueAndSaveNewCertificates generates a new key-pair, signs it with the local root-ca, and returns a
  172. // tls certificate
  173. func (rca *RootCA) IssueAndSaveNewCertificates(kw KeyWriter, cn, ou, org string) (*tls.Certificate, error) {
  174. csr, key, err := GenerateNewCSR()
  175. if err != nil {
  176. return nil, errors.Wrap(err, "error when generating new node certs")
  177. }
  178. // Obtain a signed Certificate
  179. certChain, err := rca.ParseValidateAndSignCSR(csr, cn, ou, org)
  180. if err != nil {
  181. return nil, errors.Wrap(err, "failed to sign node certificate")
  182. }
  183. // Create a valid TLSKeyPair out of the PEM encoded private key and certificate
  184. tlsKeyPair, err := tls.X509KeyPair(certChain, key)
  185. if err != nil {
  186. return nil, err
  187. }
  188. if err := kw.Write(certChain, key, nil); err != nil {
  189. return nil, err
  190. }
  191. return &tlsKeyPair, nil
  192. }
  193. // RequestAndSaveNewCertificates gets new certificates issued, either by signing them locally if a signer is
  194. // available, or by requesting them from the remote server at remoteAddr.
  195. func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWriter, config CertificateRequestConfig) (*tls.Certificate, error) {
  196. // Create a new key/pair and CSR
  197. csr, key, err := GenerateNewCSR()
  198. if err != nil {
  199. return nil, errors.Wrap(err, "error when generating new node certs")
  200. }
  201. // Get the remote manager to issue a CA signed certificate for this node
  202. // Retry up to 5 times in case the manager we first try to contact isn't
  203. // responding properly (for example, it may have just been demoted).
  204. var signedCert []byte
  205. for i := 0; i != 5; i++ {
  206. signedCert, err = GetRemoteSignedCertificate(ctx, csr, rca.Pool, config)
  207. if err == nil {
  208. break
  209. }
  210. // If the first attempt fails, we should try a remote
  211. // connection. The local node may be a manager that was
  212. // demoted, so the local connection (which is preferred) may
  213. // not work. If we are successful in renewing the certificate,
  214. // the local connection will not be returned by the connection
  215. // broker anymore.
  216. config.ForceRemote = true
  217. }
  218. if err != nil {
  219. return nil, err
  220. }
  221. // Доверяй, но проверяй.
  222. // Before we overwrite our local key + certificate, let's make sure the server gave us one that is valid
  223. // Create an X509Cert so we can .Verify()
  224. // Check to see if this certificate was signed by our CA, and isn't expired
  225. parsedCerts, err := ValidateCertChain(rca.Pool, signedCert, false)
  226. if err != nil {
  227. return nil, err
  228. }
  229. // Create a valid TLSKeyPair out of the PEM encoded private key and certificate
  230. tlsKeyPair, err := tls.X509KeyPair(signedCert, key)
  231. if err != nil {
  232. return nil, err
  233. }
  234. var kekUpdate *KEKData
  235. for i := 0; i < 5; i++ {
  236. // ValidateCertChain will always return at least 1 cert, so indexing at 0 is safe
  237. kekUpdate, err = rca.getKEKUpdate(ctx, parsedCerts[0], tlsKeyPair, config.ConnBroker)
  238. if err == nil {
  239. break
  240. }
  241. }
  242. if err != nil {
  243. return nil, err
  244. }
  245. if err := kw.Write(signedCert, key, kekUpdate); err != nil {
  246. return nil, err
  247. }
  248. return &tlsKeyPair, nil
  249. }
  250. func (rca *RootCA) getKEKUpdate(ctx context.Context, cert *x509.Certificate, keypair tls.Certificate, connBroker *connectionbroker.Broker) (*KEKData, error) {
  251. var managerRole bool
  252. for _, ou := range cert.Subject.OrganizationalUnit {
  253. if ou == ManagerRole {
  254. managerRole = true
  255. break
  256. }
  257. }
  258. if managerRole {
  259. mtlsCreds := credentials.NewTLS(&tls.Config{ServerName: CARole, RootCAs: rca.Pool, Certificates: []tls.Certificate{keypair}})
  260. conn, err := getGRPCConnection(mtlsCreds, connBroker, false)
  261. if err != nil {
  262. return nil, err
  263. }
  264. client := api.NewCAClient(conn.ClientConn)
  265. ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
  266. defer cancel()
  267. response, err := client.GetUnlockKey(ctx, &api.GetUnlockKeyRequest{})
  268. if err != nil {
  269. if grpc.Code(err) == codes.Unimplemented { // if the server does not support keks, return as if no encryption key was specified
  270. conn.Close(true)
  271. return &KEKData{}, nil
  272. }
  273. conn.Close(false)
  274. return nil, err
  275. }
  276. conn.Close(true)
  277. return &KEKData{KEK: response.UnlockKey, Version: response.Version.Index}, nil
  278. }
  279. // If this is a worker, set to never encrypt. We always want to set to the lock key to nil,
  280. // in case this was a manager that was demoted to a worker.
  281. return &KEKData{}, nil
  282. }
  283. // PrepareCSR creates a CFSSL Sign Request based on the given raw CSR and
  284. // overrides the Subject and Hosts with the given extra args.
  285. func PrepareCSR(csrBytes []byte, cn, ou, org string) cfsigner.SignRequest {
  286. // All managers get added the subject-alt-name of CA, so they can be
  287. // used for cert issuance.
  288. hosts := []string{ou, cn}
  289. if ou == ManagerRole {
  290. hosts = append(hosts, CARole)
  291. }
  292. return cfsigner.SignRequest{
  293. Request: string(csrBytes),
  294. // OU is used for Authentication of the node type. The CN has the random
  295. // node ID.
  296. Subject: &cfsigner.Subject{CN: cn, Names: []cfcsr.Name{{OU: ou, O: org}}},
  297. // Adding ou as DNS alt name, so clients can connect to ManagerRole and CARole
  298. Hosts: hosts,
  299. }
  300. }
  301. // ParseValidateAndSignCSR returns a signed certificate from a particular rootCA and a CSR.
  302. func (rca *RootCA) ParseValidateAndSignCSR(csrBytes []byte, cn, ou, org string) ([]byte, error) {
  303. signRequest := PrepareCSR(csrBytes, cn, ou, org)
  304. signer, err := rca.Signer()
  305. if err != nil {
  306. return nil, err
  307. }
  308. cert, err := signer.Sign(signRequest)
  309. if err != nil {
  310. return nil, errors.Wrap(err, "failed to sign node certificate")
  311. }
  312. return append(cert, rca.Intermediates...), nil
  313. }
  314. // CrossSignCACertificate takes a CA root certificate and generates an intermediate CA from it signed with the current root signer
  315. func (rca *RootCA) CrossSignCACertificate(otherCAPEM []byte) ([]byte, error) {
  316. signer, err := rca.Signer()
  317. if err != nil {
  318. return nil, err
  319. }
  320. // create a new cert with exactly the same parameters, including the public key and exact NotBefore and NotAfter
  321. newCert, err := helpers.ParseCertificatePEM(otherCAPEM)
  322. if err != nil {
  323. return nil, errors.New("could not parse new CA certificate")
  324. }
  325. if !newCert.IsCA {
  326. return nil, errors.New("certificate not a CA")
  327. }
  328. derBytes, err := x509.CreateCertificate(cryptorand.Reader, newCert, signer.parsedCert, newCert.PublicKey, signer.cryptoSigner)
  329. if err != nil {
  330. return nil, errors.Wrap(err, "could not cross-sign new CA certificate using old CA material")
  331. }
  332. return pem.EncodeToMemory(&pem.Block{
  333. Type: "CERTIFICATE",
  334. Bytes: derBytes,
  335. }), nil
  336. }
  337. func validateSignatureAlgorithm(cert *x509.Certificate) error {
  338. switch cert.SignatureAlgorithm {
  339. case x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA, x509.ECDSAWithSHA256, x509.ECDSAWithSHA384, x509.ECDSAWithSHA512:
  340. return nil
  341. default:
  342. return fmt.Errorf("unsupported signature algorithm: %s", cert.SignatureAlgorithm.String())
  343. }
  344. }
  345. // NewRootCA creates a new RootCA object from unparsed PEM cert bundle and key byte
  346. // slices. key may be nil, and in this case NewRootCA will return a RootCA
  347. // without a signer.
  348. func NewRootCA(rootCertBytes, signCertBytes, signKeyBytes []byte, certExpiry time.Duration, intermediates []byte) (RootCA, error) {
  349. // Parse all the certificates in the cert bundle
  350. parsedCerts, err := helpers.ParseCertificatesPEM(rootCertBytes)
  351. if err != nil {
  352. return RootCA{}, errors.Wrap(err, "invalid root certificates")
  353. }
  354. // Check to see if we have at least one valid cert
  355. if len(parsedCerts) < 1 {
  356. return RootCA{}, errors.New("no valid root CA certificates found")
  357. }
  358. // Create a Pool with all of the certificates found
  359. pool := x509.NewCertPool()
  360. for _, cert := range parsedCerts {
  361. if err := validateSignatureAlgorithm(cert); err != nil {
  362. return RootCA{}, err
  363. }
  364. // Check to see if all of the certificates are valid, self-signed root CA certs
  365. selfpool := x509.NewCertPool()
  366. selfpool.AddCert(cert)
  367. if _, err := cert.Verify(x509.VerifyOptions{Roots: selfpool}); err != nil {
  368. return RootCA{}, errors.Wrap(err, "error while validating Root CA Certificate")
  369. }
  370. pool.AddCert(cert)
  371. }
  372. // Calculate the digest for our Root CA bundle
  373. digest := digest.FromBytes(rootCertBytes)
  374. // The intermediates supplied must be able to chain up to the root certificates, so that when they are appended to
  375. // a leaf certificate, the leaf certificate can be validated through the intermediates to the root certificates.
  376. var intermediatePool *x509.CertPool
  377. var parsedIntermediates []*x509.Certificate
  378. if len(intermediates) > 0 {
  379. parsedIntermediates, err = ValidateCertChain(pool, intermediates, false)
  380. if err != nil {
  381. return RootCA{}, errors.Wrap(err, "invalid intermediate chain")
  382. }
  383. intermediatePool = x509.NewCertPool()
  384. for _, cert := range parsedIntermediates {
  385. intermediatePool.AddCert(cert)
  386. }
  387. }
  388. var localSigner *LocalSigner
  389. if len(signKeyBytes) != 0 || len(signCertBytes) != 0 {
  390. localSigner, err = newLocalSigner(signKeyBytes, signCertBytes, certExpiry, pool, intermediatePool)
  391. if err != nil {
  392. return RootCA{}, err
  393. }
  394. // If a signer is provided and there are intermediates, then either the first intermediate would be the signer CA
  395. // certificate (in which case it'd have the same subject and public key), or it would be a cross-signed
  396. // intermediate with the same subject and public key as our signing CA certificate (which could be either an
  397. // intermediate cert or a self-signed root cert).
  398. if len(parsedIntermediates) > 0 && (!bytes.Equal(parsedIntermediates[0].RawSubject, localSigner.parsedCert.RawSubject) ||
  399. !bytes.Equal(parsedIntermediates[0].RawSubjectPublicKeyInfo, localSigner.parsedCert.RawSubjectPublicKeyInfo)) {
  400. return RootCA{}, errors.New(
  401. "invalid intermediate chain - the first intermediate must have the same subject and public key as the signing cert")
  402. }
  403. }
  404. return RootCA{signer: localSigner, Intermediates: intermediates, Digest: digest, Certs: rootCertBytes, Pool: pool}, nil
  405. }
  406. // ValidateCertChain checks checks that the certificates provided chain up to the root pool provided. In addition
  407. // it also enforces that every cert in the bundle certificates form a chain, each one certifying the one above,
  408. // as per RFC5246 section 7.4.2, and that every certificate (whether or not it is necessary to form a chain to the root
  409. // pool) is currently valid and not yet expired (unless allowExpiry is set to true).
  410. // This is additional validation not required by go's Certificate.Verify (which allows invalid certs in the
  411. // intermediate pool), because this function is intended to be used when reading certs from untrusted locations such as
  412. // from disk or over a network when a CSR is signed, so it is extra pedantic.
  413. // This function always returns all the parsed certificates in the bundle in order, which means there will always be
  414. // at least 1 certificate if there is no error.
  415. func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool) ([]*x509.Certificate, error) {
  416. // Parse all the certificates in the cert bundle
  417. parsedCerts, err := helpers.ParseCertificatesPEM(certs)
  418. if err != nil {
  419. return nil, err
  420. }
  421. if len(parsedCerts) == 0 {
  422. return nil, errors.New("no certificates to validate")
  423. }
  424. now := time.Now()
  425. // ensure that they form a chain, each one being signed by the one after it
  426. var intermediatePool *x509.CertPool
  427. for i, cert := range parsedCerts {
  428. // Manual expiry validation because we want more information on which certificate in the chain is expired, and
  429. // because this is an easier way to allow expired certs.
  430. if now.Before(cert.NotBefore) {
  431. return nil, errors.Wrapf(
  432. x509.CertificateInvalidError{
  433. Cert: cert,
  434. Reason: x509.Expired,
  435. },
  436. "certificate (%d - %s) not valid before %s, and it is currently %s",
  437. i+1, cert.Subject.CommonName, cert.NotBefore.UTC().Format(time.RFC1123), now.Format(time.RFC1123))
  438. }
  439. if !allowExpired && now.After(cert.NotAfter) {
  440. return nil, errors.Wrapf(
  441. x509.CertificateInvalidError{
  442. Cert: cert,
  443. Reason: x509.Expired,
  444. },
  445. "certificate (%d - %s) not valid after %s, and it is currently %s",
  446. i+1, cert.Subject.CommonName, cert.NotAfter.UTC().Format(time.RFC1123), now.Format(time.RFC1123))
  447. }
  448. if i > 0 {
  449. // check that the previous cert was signed by this cert
  450. prevCert := parsedCerts[i-1]
  451. if err := prevCert.CheckSignatureFrom(cert); err != nil {
  452. return nil, errors.Wrapf(err, "certificates do not form a chain: (%d - %s) is not signed by (%d - %s)",
  453. i, prevCert.Subject.CommonName, i+1, cert.Subject.CommonName)
  454. }
  455. if intermediatePool == nil {
  456. intermediatePool = x509.NewCertPool()
  457. }
  458. intermediatePool.AddCert(cert)
  459. }
  460. }
  461. verifyOpts := x509.VerifyOptions{
  462. Roots: rootPool,
  463. Intermediates: intermediatePool,
  464. CurrentTime: now,
  465. }
  466. // If we accept expired certs, try to build a valid cert chain using some subset of the certs. We start off using the
  467. // first certificate's NotAfter as the current time, thus ensuring that the first cert is not expired. If the chain
  468. // still fails to validate due to expiry issues, continue iterating over the rest of the certs.
  469. // If any of the other certs has an earlier NotAfter time, use that time as the current time instead. This insures that
  470. // particular cert, and any that came before it, are not expired. Note that the root that the certs chain up to
  471. // should also not be expired at that "current" time.
  472. if allowExpired {
  473. verifyOpts.CurrentTime = parsedCerts[0].NotAfter.Add(time.Hour)
  474. for _, cert := range parsedCerts {
  475. if !cert.NotAfter.Before(verifyOpts.CurrentTime) {
  476. continue
  477. }
  478. verifyOpts.CurrentTime = cert.NotAfter
  479. _, err = parsedCerts[0].Verify(verifyOpts)
  480. if err == nil {
  481. return parsedCerts, nil
  482. }
  483. }
  484. if invalid, ok := err.(x509.CertificateInvalidError); ok && invalid.Reason == x509.Expired {
  485. return nil, errors.New("there is no time span for which all of the certificates, including a root, are valid")
  486. }
  487. return nil, err
  488. }
  489. _, err = parsedCerts[0].Verify(verifyOpts)
  490. if err != nil {
  491. return nil, err
  492. }
  493. return parsedCerts, nil
  494. }
  495. // newLocalSigner validates the signing cert and signing key to create a local signer, which accepts a crypto signer and a cert
  496. func newLocalSigner(keyBytes, certBytes []byte, certExpiry time.Duration, rootPool, intermediatePool *x509.CertPool) (*LocalSigner, error) {
  497. if len(keyBytes) == 0 || len(certBytes) == 0 {
  498. return nil, errors.New("must provide both a signing key and a signing cert, or neither")
  499. }
  500. parsedCerts, err := helpers.ParseCertificatesPEM(certBytes)
  501. if err != nil {
  502. return nil, errors.Wrap(err, "invalid signing CA cert")
  503. }
  504. if len(parsedCerts) == 0 {
  505. return nil, errors.New("no valid signing CA certificates found")
  506. }
  507. if err := validateSignatureAlgorithm(parsedCerts[0]); err != nil {
  508. return nil, err
  509. }
  510. opts := x509.VerifyOptions{
  511. Roots: rootPool,
  512. Intermediates: intermediatePool,
  513. }
  514. if _, err := parsedCerts[0].Verify(opts); err != nil {
  515. return nil, errors.Wrap(err, "error while validating signing CA certificate against roots and intermediates")
  516. }
  517. var (
  518. passphraseStr string
  519. passphrase, passphrasePrev []byte
  520. priv crypto.Signer
  521. )
  522. // Attempt two distinct passphrases, so we can do a hitless passphrase rotation
  523. if passphraseStr = os.Getenv(PassphraseENVVar); passphraseStr != "" {
  524. passphrase = []byte(passphraseStr)
  525. }
  526. if p := os.Getenv(PassphraseENVVarPrev); p != "" {
  527. passphrasePrev = []byte(p)
  528. }
  529. // Attempt to decrypt the current private-key with the passphrases provided
  530. priv, err = helpers.ParsePrivateKeyPEMWithPassword(keyBytes, passphrase)
  531. if err != nil {
  532. priv, err = helpers.ParsePrivateKeyPEMWithPassword(keyBytes, passphrasePrev)
  533. if err != nil {
  534. return nil, errors.Wrap(err, "malformed private key")
  535. }
  536. }
  537. // We will always use the first certificate inside of the root bundle as the active one
  538. if err := ensureCertKeyMatch(parsedCerts[0], priv.Public()); err != nil {
  539. return nil, err
  540. }
  541. signer, err := local.NewSigner(priv, parsedCerts[0], cfsigner.DefaultSigAlgo(priv), SigningPolicy(certExpiry))
  542. if err != nil {
  543. return nil, err
  544. }
  545. // If the key was loaded from disk unencrypted, but there is a passphrase set,
  546. // ensure it is encrypted, so it doesn't hit raft in plain-text
  547. // we don't have to check for nil, because if we couldn't pem-decode the bytes, then parsing above would have failed
  548. keyBlock, _ := pem.Decode(keyBytes)
  549. if passphraseStr != "" && !x509.IsEncryptedPEMBlock(keyBlock) {
  550. keyBytes, err = EncryptECPrivateKey(keyBytes, passphraseStr)
  551. if err != nil {
  552. return nil, errors.Wrap(err, "unable to encrypt signing CA key material")
  553. }
  554. }
  555. return &LocalSigner{Cert: certBytes, Key: keyBytes, Signer: signer, parsedCert: parsedCerts[0], cryptoSigner: priv}, nil
  556. }
  557. func ensureCertKeyMatch(cert *x509.Certificate, key crypto.PublicKey) error {
  558. switch certPub := cert.PublicKey.(type) {
  559. case *rsa.PublicKey:
  560. if certPub.N.BitLen() < 2048 || certPub.E == 1 {
  561. return errors.New("unsupported RSA key parameters")
  562. }
  563. rsaKey, ok := key.(*rsa.PublicKey)
  564. if ok && certPub.E == rsaKey.E && certPub.N.Cmp(rsaKey.N) == 0 {
  565. return nil
  566. }
  567. case *ecdsa.PublicKey:
  568. switch certPub.Curve {
  569. case elliptic.P256(), elliptic.P384(), elliptic.P521():
  570. break
  571. default:
  572. return errors.New("unsupported ECDSA key parameters")
  573. }
  574. ecKey, ok := key.(*ecdsa.PublicKey)
  575. if ok && certPub.X.Cmp(ecKey.X) == 0 && certPub.Y.Cmp(ecKey.Y) == 0 {
  576. return nil
  577. }
  578. default:
  579. return errors.New("unknown or unsupported certificate public key algorithm")
  580. }
  581. return errors.New("certificate key mismatch")
  582. }
  583. // GetLocalRootCA validates if the contents of the file are a valid self-signed
  584. // CA certificate, and returns the PEM-encoded Certificate if so
  585. func GetLocalRootCA(paths CertPaths) (RootCA, error) {
  586. // Check if we have a Certificate file
  587. cert, err := ioutil.ReadFile(paths.Cert)
  588. if err != nil {
  589. if os.IsNotExist(err) {
  590. err = ErrNoLocalRootCA
  591. }
  592. return RootCA{}, err
  593. }
  594. signingCert := cert
  595. key, err := ioutil.ReadFile(paths.Key)
  596. if err != nil {
  597. if !os.IsNotExist(err) {
  598. return RootCA{}, err
  599. }
  600. // There may not be a local key. It's okay to pass in a nil
  601. // key. We'll get a root CA without a signer.
  602. key = nil
  603. signingCert = nil
  604. }
  605. return NewRootCA(cert, signingCert, key, DefaultNodeCertExpiration, nil)
  606. }
  607. func getGRPCConnection(creds credentials.TransportCredentials, connBroker *connectionbroker.Broker, forceRemote bool) (*connectionbroker.Conn, error) {
  608. dialOpts := []grpc.DialOption{
  609. grpc.WithTransportCredentials(creds),
  610. grpc.WithTimeout(5 * time.Second),
  611. grpc.WithBackoffMaxDelay(5 * time.Second),
  612. }
  613. if forceRemote {
  614. return connBroker.SelectRemote(dialOpts...)
  615. }
  616. return connBroker.Select(dialOpts...)
  617. }
  618. // GetRemoteCA returns the remote endpoint's CA certificate bundle
  619. func GetRemoteCA(ctx context.Context, d digest.Digest, connBroker *connectionbroker.Broker) (RootCA, error) {
  620. // This TLS Config is intentionally using InsecureSkipVerify. We use the
  621. // digest instead to check the integrity of the CA certificate.
  622. insecureCreds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})
  623. conn, err := getGRPCConnection(insecureCreds, connBroker, false)
  624. if err != nil {
  625. return RootCA{}, err
  626. }
  627. client := api.NewCAClient(conn.ClientConn)
  628. ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
  629. defer cancel()
  630. defer func() {
  631. conn.Close(err == nil)
  632. }()
  633. response, err := client.GetRootCACertificate(ctx, &api.GetRootCACertificateRequest{})
  634. if err != nil {
  635. return RootCA{}, err
  636. }
  637. // If a bundle of certificates are provided, the digest covers the entire bundle and not just
  638. // one of the certificates in the bundle. Otherwise, a node can be MITMed while joining if
  639. // the MITM CA provides a single certificate which matches the digest, and providing arbitrary
  640. // other non-verified root certs that the manager certificate actually chains up to.
  641. if d != "" {
  642. verifier := d.Verifier()
  643. if err != nil {
  644. return RootCA{}, errors.Wrap(err, "unexpected error getting digest verifier")
  645. }
  646. io.Copy(verifier, bytes.NewReader(response.Certificate))
  647. if !verifier.Verified() {
  648. return RootCA{}, errors.Errorf("remote CA does not match fingerprint. Expected: %s", d.Hex())
  649. }
  650. }
  651. // NewRootCA will validate that the certificates are otherwise valid and create a RootCA object.
  652. // Since there is no key, the certificate expiry does not matter and will not be used.
  653. return NewRootCA(response.Certificate, nil, nil, DefaultNodeCertExpiration, nil)
  654. }
  655. // CreateRootCA creates a Certificate authority for a new Swarm Cluster, potentially
  656. // overwriting any existing CAs.
  657. func CreateRootCA(rootCN string) (RootCA, error) {
  658. // Create a simple CSR for the CA using the default CA validator and policy
  659. req := cfcsr.CertificateRequest{
  660. CN: rootCN,
  661. KeyRequest: &cfcsr.BasicKeyRequest{A: RootKeyAlgo, S: RootKeySize},
  662. CA: &cfcsr.CAConfig{Expiry: RootCAExpiration},
  663. }
  664. // Generate the CA and get the certificate and private key
  665. cert, _, key, err := initca.New(&req)
  666. if err != nil {
  667. return RootCA{}, err
  668. }
  669. rootCA, err := NewRootCA(cert, cert, key, DefaultNodeCertExpiration, nil)
  670. if err != nil {
  671. return RootCA{}, err
  672. }
  673. return rootCA, nil
  674. }
  675. // GetRemoteSignedCertificate submits a CSR to a remote CA server address,
  676. // and that is part of a CA identified by a specific certificate pool.
  677. func GetRemoteSignedCertificate(ctx context.Context, csr []byte, rootCAPool *x509.CertPool, config CertificateRequestConfig) ([]byte, error) {
  678. if rootCAPool == nil {
  679. return nil, errors.New("valid root CA pool required")
  680. }
  681. creds := config.Credentials
  682. if creds == nil {
  683. // This is our only non-MTLS request, and it happens when we are boostraping our TLS certs
  684. // We're using CARole as server name, so an external CA doesn't also have to have ManagerRole in the cert SANs
  685. creds = credentials.NewTLS(&tls.Config{ServerName: CARole, RootCAs: rootCAPool})
  686. }
  687. conn, err := getGRPCConnection(creds, config.ConnBroker, config.ForceRemote)
  688. if err != nil {
  689. return nil, err
  690. }
  691. // Create a CAClient to retrieve a new Certificate
  692. caClient := api.NewNodeCAClient(conn.ClientConn)
  693. issueCtx, issueCancel := context.WithTimeout(ctx, 5*time.Second)
  694. defer issueCancel()
  695. // Send the Request and retrieve the request token
  696. issueRequest := &api.IssueNodeCertificateRequest{CSR: csr, Token: config.Token, Availability: config.Availability}
  697. issueResponse, err := caClient.IssueNodeCertificate(issueCtx, issueRequest)
  698. if err != nil {
  699. conn.Close(false)
  700. return nil, err
  701. }
  702. statusRequest := &api.NodeCertificateStatusRequest{NodeID: issueResponse.NodeID}
  703. expBackoff := events.NewExponentialBackoff(events.ExponentialBackoffConfig{
  704. Base: time.Second,
  705. Factor: time.Second,
  706. Max: 30 * time.Second,
  707. })
  708. // Exponential backoff with Max of 30 seconds to wait for a new retry
  709. for {
  710. // Send the Request and retrieve the certificate
  711. ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
  712. defer cancel()
  713. statusResponse, err := caClient.NodeCertificateStatus(ctx, statusRequest)
  714. if err != nil {
  715. conn.Close(false)
  716. return nil, err
  717. }
  718. // If the certificate was issued, return
  719. if statusResponse.Status.State == api.IssuanceStateIssued {
  720. if statusResponse.Certificate == nil {
  721. conn.Close(false)
  722. return nil, errors.New("no certificate in CertificateStatus response")
  723. }
  724. // The certificate in the response must match the CSR
  725. // we submitted. If we are getting a response for a
  726. // certificate that was previously issued, we need to
  727. // retry until the certificate gets updated per our
  728. // current request.
  729. if bytes.Equal(statusResponse.Certificate.CSR, csr) {
  730. conn.Close(true)
  731. return statusResponse.Certificate.Certificate, nil
  732. }
  733. }
  734. // If we're still pending, the issuance failed, or the state is unknown
  735. // let's continue trying.
  736. expBackoff.Failure(nil, nil)
  737. time.Sleep(expBackoff.Proceed(nil))
  738. }
  739. }
  740. // readCertValidity returns the certificate issue and expiration time
  741. func readCertValidity(kr KeyReader) (time.Time, time.Time, error) {
  742. var zeroTime time.Time
  743. // Read the Cert
  744. cert, _, err := kr.Read()
  745. if err != nil {
  746. return zeroTime, zeroTime, err
  747. }
  748. // Create an x509 certificate out of the contents on disk
  749. certBlock, _ := pem.Decode(cert)
  750. if certBlock == nil {
  751. return zeroTime, zeroTime, errors.New("failed to decode certificate block")
  752. }
  753. X509Cert, err := x509.ParseCertificate(certBlock.Bytes)
  754. if err != nil {
  755. return zeroTime, zeroTime, err
  756. }
  757. return X509Cert.NotBefore, X509Cert.NotAfter, nil
  758. }
  759. // SaveRootCA saves a RootCA object to disk
  760. func SaveRootCA(rootCA RootCA, paths CertPaths) error {
  761. // Make sure the necessary dirs exist and they are writable
  762. err := os.MkdirAll(filepath.Dir(paths.Cert), 0755)
  763. if err != nil {
  764. return err
  765. }
  766. // If the root certificate got returned successfully, save the rootCA to disk.
  767. return ioutils.AtomicWriteFile(paths.Cert, rootCA.Certs, 0644)
  768. }
  769. // GenerateNewCSR returns a newly generated key and CSR signed with said key
  770. func GenerateNewCSR() ([]byte, []byte, error) {
  771. req := &cfcsr.CertificateRequest{
  772. KeyRequest: cfcsr.NewBasicKeyRequest(),
  773. }
  774. return cfcsr.ParseRequest(req)
  775. }
  776. // EncryptECPrivateKey receives a PEM encoded private key and returns an encrypted
  777. // AES256 version using a passphrase
  778. // TODO: Make this method generic to handle RSA keys
  779. func EncryptECPrivateKey(key []byte, passphraseStr string) ([]byte, error) {
  780. passphrase := []byte(passphraseStr)
  781. cipherType := x509.PEMCipherAES256
  782. keyBlock, _ := pem.Decode(key)
  783. if keyBlock == nil {
  784. // This RootCA does not have a valid signer.
  785. return nil, errors.New("error while decoding PEM key")
  786. }
  787. encryptedPEMBlock, err := x509.EncryptPEMBlock(cryptorand.Reader,
  788. "EC PRIVATE KEY",
  789. keyBlock.Bytes,
  790. passphrase,
  791. cipherType)
  792. if err != nil {
  793. return nil, err
  794. }
  795. if encryptedPEMBlock.Headers == nil {
  796. return nil, errors.New("unable to encrypt key - invalid PEM file produced")
  797. }
  798. return pem.EncodeToMemory(encryptedPEMBlock), nil
  799. }