local.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. // Package local implements certificate signature functionality for CFSSL.
  2. package local
  3. import (
  4. "bytes"
  5. "crypto"
  6. "crypto/rand"
  7. "crypto/x509"
  8. "crypto/x509/pkix"
  9. "encoding/asn1"
  10. "encoding/binary"
  11. "encoding/hex"
  12. "encoding/pem"
  13. "errors"
  14. "io"
  15. "io/ioutil"
  16. "math/big"
  17. "net"
  18. "net/mail"
  19. "os"
  20. "github.com/cloudflare/cfssl/certdb"
  21. "github.com/cloudflare/cfssl/config"
  22. cferr "github.com/cloudflare/cfssl/errors"
  23. "github.com/cloudflare/cfssl/helpers"
  24. "github.com/cloudflare/cfssl/info"
  25. "github.com/cloudflare/cfssl/log"
  26. "github.com/cloudflare/cfssl/signer"
  27. "github.com/google/certificate-transparency/go"
  28. "github.com/google/certificate-transparency/go/client"
  29. )
  30. // Signer contains a signer that uses the standard library to
  31. // support both ECDSA and RSA CA keys.
  32. type Signer struct {
  33. ca *x509.Certificate
  34. priv crypto.Signer
  35. policy *config.Signing
  36. sigAlgo x509.SignatureAlgorithm
  37. dbAccessor certdb.Accessor
  38. }
  39. // NewSigner creates a new Signer directly from a
  40. // private key and certificate, with optional policy.
  41. func NewSigner(priv crypto.Signer, cert *x509.Certificate, sigAlgo x509.SignatureAlgorithm, policy *config.Signing) (*Signer, error) {
  42. if policy == nil {
  43. policy = &config.Signing{
  44. Profiles: map[string]*config.SigningProfile{},
  45. Default: config.DefaultConfig()}
  46. }
  47. if !policy.Valid() {
  48. return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy)
  49. }
  50. return &Signer{
  51. ca: cert,
  52. priv: priv,
  53. sigAlgo: sigAlgo,
  54. policy: policy,
  55. }, nil
  56. }
  57. // NewSignerFromFile generates a new local signer from a caFile
  58. // and a caKey file, both PEM encoded.
  59. func NewSignerFromFile(caFile, caKeyFile string, policy *config.Signing) (*Signer, error) {
  60. log.Debug("Loading CA: ", caFile)
  61. ca, err := ioutil.ReadFile(caFile)
  62. if err != nil {
  63. return nil, err
  64. }
  65. log.Debug("Loading CA key: ", caKeyFile)
  66. cakey, err := ioutil.ReadFile(caKeyFile)
  67. if err != nil {
  68. return nil, cferr.Wrap(cferr.CertificateError, cferr.ReadFailed, err)
  69. }
  70. parsedCa, err := helpers.ParseCertificatePEM(ca)
  71. if err != nil {
  72. return nil, err
  73. }
  74. strPassword := os.Getenv("CFSSL_CA_PK_PASSWORD")
  75. password := []byte(strPassword)
  76. if strPassword == "" {
  77. password = nil
  78. }
  79. priv, err := helpers.ParsePrivateKeyPEMWithPassword(cakey, password)
  80. if err != nil {
  81. log.Debug("Malformed private key %v", err)
  82. return nil, err
  83. }
  84. return NewSigner(priv, parsedCa, signer.DefaultSigAlgo(priv), policy)
  85. }
  86. func (s *Signer) sign(template *x509.Certificate, profile *config.SigningProfile) (cert []byte, err error) {
  87. var distPoints = template.CRLDistributionPoints
  88. err = signer.FillTemplate(template, s.policy.Default, profile)
  89. if distPoints != nil && len(distPoints) > 0 {
  90. template.CRLDistributionPoints = distPoints
  91. }
  92. if err != nil {
  93. return
  94. }
  95. var initRoot bool
  96. if s.ca == nil {
  97. if !template.IsCA {
  98. err = cferr.New(cferr.PolicyError, cferr.InvalidRequest)
  99. return
  100. }
  101. template.DNSNames = nil
  102. template.EmailAddresses = nil
  103. s.ca = template
  104. initRoot = true
  105. }
  106. derBytes, err := x509.CreateCertificate(rand.Reader, template, s.ca, template.PublicKey, s.priv)
  107. if err != nil {
  108. return nil, cferr.Wrap(cferr.CertificateError, cferr.Unknown, err)
  109. }
  110. if initRoot {
  111. s.ca, err = x509.ParseCertificate(derBytes)
  112. if err != nil {
  113. return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
  114. }
  115. }
  116. cert = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
  117. log.Infof("signed certificate with serial number %d", template.SerialNumber)
  118. return
  119. }
  120. // replaceSliceIfEmpty replaces the contents of replaced with newContents if
  121. // the slice referenced by replaced is empty
  122. func replaceSliceIfEmpty(replaced, newContents *[]string) {
  123. if len(*replaced) == 0 {
  124. *replaced = *newContents
  125. }
  126. }
  127. // PopulateSubjectFromCSR has functionality similar to Name, except
  128. // it fills the fields of the resulting pkix.Name with req's if the
  129. // subject's corresponding fields are empty
  130. func PopulateSubjectFromCSR(s *signer.Subject, req pkix.Name) pkix.Name {
  131. // if no subject, use req
  132. if s == nil {
  133. return req
  134. }
  135. name := s.Name()
  136. if name.CommonName == "" {
  137. name.CommonName = req.CommonName
  138. }
  139. replaceSliceIfEmpty(&name.Country, &req.Country)
  140. replaceSliceIfEmpty(&name.Province, &req.Province)
  141. replaceSliceIfEmpty(&name.Locality, &req.Locality)
  142. replaceSliceIfEmpty(&name.Organization, &req.Organization)
  143. replaceSliceIfEmpty(&name.OrganizationalUnit, &req.OrganizationalUnit)
  144. if name.SerialNumber == "" {
  145. name.SerialNumber = req.SerialNumber
  146. }
  147. return name
  148. }
  149. // OverrideHosts fills template's IPAddresses, EmailAddresses, and DNSNames with the
  150. // content of hosts, if it is not nil.
  151. func OverrideHosts(template *x509.Certificate, hosts []string) {
  152. if hosts != nil {
  153. template.IPAddresses = []net.IP{}
  154. template.EmailAddresses = []string{}
  155. template.DNSNames = []string{}
  156. }
  157. for i := range hosts {
  158. if ip := net.ParseIP(hosts[i]); ip != nil {
  159. template.IPAddresses = append(template.IPAddresses, ip)
  160. } else if email, err := mail.ParseAddress(hosts[i]); err == nil && email != nil {
  161. template.EmailAddresses = append(template.EmailAddresses, email.Address)
  162. } else {
  163. template.DNSNames = append(template.DNSNames, hosts[i])
  164. }
  165. }
  166. }
  167. // Sign signs a new certificate based on the PEM-encoded client
  168. // certificate or certificate request with the signing profile,
  169. // specified by profileName.
  170. func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
  171. profile, err := signer.Profile(s, req.Profile)
  172. if err != nil {
  173. return
  174. }
  175. block, _ := pem.Decode([]byte(req.Request))
  176. if block == nil {
  177. return nil, cferr.New(cferr.CSRError, cferr.DecodeFailed)
  178. }
  179. if block.Type != "NEW CERTIFICATE REQUEST" && block.Type != "CERTIFICATE REQUEST" {
  180. return nil, cferr.Wrap(cferr.CSRError,
  181. cferr.BadRequest, errors.New("not a certificate or csr"))
  182. }
  183. csrTemplate, err := signer.ParseCertificateRequest(s, block.Bytes)
  184. if err != nil {
  185. return nil, err
  186. }
  187. // Copy out only the fields from the CSR authorized by policy.
  188. safeTemplate := x509.Certificate{}
  189. // If the profile contains no explicit whitelist, assume that all fields
  190. // should be copied from the CSR.
  191. if profile.CSRWhitelist == nil {
  192. safeTemplate = *csrTemplate
  193. } else {
  194. if profile.CSRWhitelist.Subject {
  195. safeTemplate.Subject = csrTemplate.Subject
  196. }
  197. if profile.CSRWhitelist.PublicKeyAlgorithm {
  198. safeTemplate.PublicKeyAlgorithm = csrTemplate.PublicKeyAlgorithm
  199. }
  200. if profile.CSRWhitelist.PublicKey {
  201. safeTemplate.PublicKey = csrTemplate.PublicKey
  202. }
  203. if profile.CSRWhitelist.SignatureAlgorithm {
  204. safeTemplate.SignatureAlgorithm = csrTemplate.SignatureAlgorithm
  205. }
  206. if profile.CSRWhitelist.DNSNames {
  207. safeTemplate.DNSNames = csrTemplate.DNSNames
  208. }
  209. if profile.CSRWhitelist.IPAddresses {
  210. safeTemplate.IPAddresses = csrTemplate.IPAddresses
  211. }
  212. if profile.CSRWhitelist.EmailAddresses {
  213. safeTemplate.EmailAddresses = csrTemplate.EmailAddresses
  214. }
  215. }
  216. if req.CRLOverride != "" {
  217. safeTemplate.CRLDistributionPoints = []string{req.CRLOverride}
  218. }
  219. if safeTemplate.IsCA {
  220. if !profile.CAConstraint.IsCA {
  221. log.Error("local signer policy disallows issuing CA certificate")
  222. return nil, cferr.New(cferr.PolicyError, cferr.InvalidRequest)
  223. }
  224. if s.ca != nil && s.ca.MaxPathLen > 0 {
  225. if safeTemplate.MaxPathLen >= s.ca.MaxPathLen {
  226. log.Error("local signer certificate disallows CA MaxPathLen extending")
  227. // do not sign a cert with pathlen > current
  228. return nil, cferr.New(cferr.PolicyError, cferr.InvalidRequest)
  229. }
  230. } else if s.ca != nil && s.ca.MaxPathLen == 0 && s.ca.MaxPathLenZero {
  231. log.Error("local signer certificate disallows issuing CA certificate")
  232. // signer has pathlen of 0, do not sign more intermediate CAs
  233. return nil, cferr.New(cferr.PolicyError, cferr.InvalidRequest)
  234. }
  235. }
  236. OverrideHosts(&safeTemplate, req.Hosts)
  237. safeTemplate.Subject = PopulateSubjectFromCSR(req.Subject, safeTemplate.Subject)
  238. // If there is a whitelist, ensure that both the Common Name and SAN DNSNames match
  239. if profile.NameWhitelist != nil {
  240. if safeTemplate.Subject.CommonName != "" {
  241. if profile.NameWhitelist.Find([]byte(safeTemplate.Subject.CommonName)) == nil {
  242. return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist)
  243. }
  244. }
  245. for _, name := range safeTemplate.DNSNames {
  246. if profile.NameWhitelist.Find([]byte(name)) == nil {
  247. return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist)
  248. }
  249. }
  250. for _, name := range safeTemplate.EmailAddresses {
  251. if profile.NameWhitelist.Find([]byte(name)) == nil {
  252. return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist)
  253. }
  254. }
  255. }
  256. if profile.ClientProvidesSerialNumbers {
  257. if req.Serial == nil {
  258. return nil, cferr.New(cferr.CertificateError, cferr.MissingSerial)
  259. }
  260. safeTemplate.SerialNumber = req.Serial
  261. } else {
  262. // RFC 5280 4.1.2.2:
  263. // Certificate users MUST be able to handle serialNumber
  264. // values up to 20 octets. Conforming CAs MUST NOT use
  265. // serialNumber values longer than 20 octets.
  266. //
  267. // If CFSSL is providing the serial numbers, it makes
  268. // sense to use the max supported size.
  269. serialNumber := make([]byte, 20)
  270. _, err = io.ReadFull(rand.Reader, serialNumber)
  271. if err != nil {
  272. return nil, cferr.Wrap(cferr.CertificateError, cferr.Unknown, err)
  273. }
  274. // SetBytes interprets buf as the bytes of a big-endian
  275. // unsigned integer. The leading byte should be masked
  276. // off to ensure it isn't negative.
  277. serialNumber[0] &= 0x7F
  278. safeTemplate.SerialNumber = new(big.Int).SetBytes(serialNumber)
  279. }
  280. if len(req.Extensions) > 0 {
  281. for _, ext := range req.Extensions {
  282. oid := asn1.ObjectIdentifier(ext.ID)
  283. if !profile.ExtensionWhitelist[oid.String()] {
  284. return nil, cferr.New(cferr.CertificateError, cferr.InvalidRequest)
  285. }
  286. rawValue, err := hex.DecodeString(ext.Value)
  287. if err != nil {
  288. return nil, cferr.Wrap(cferr.CertificateError, cferr.InvalidRequest, err)
  289. }
  290. safeTemplate.ExtraExtensions = append(safeTemplate.ExtraExtensions, pkix.Extension{
  291. Id: oid,
  292. Critical: ext.Critical,
  293. Value: rawValue,
  294. })
  295. }
  296. }
  297. var certTBS = safeTemplate
  298. if len(profile.CTLogServers) > 0 {
  299. // Add a poison extension which prevents validation
  300. var poisonExtension = pkix.Extension{Id: signer.CTPoisonOID, Critical: true, Value: []byte{0x05, 0x00}}
  301. var poisonedPreCert = certTBS
  302. poisonedPreCert.ExtraExtensions = append(safeTemplate.ExtraExtensions, poisonExtension)
  303. cert, err = s.sign(&poisonedPreCert, profile)
  304. if err != nil {
  305. return
  306. }
  307. derCert, _ := pem.Decode(cert)
  308. prechain := []ct.ASN1Cert{derCert.Bytes, s.ca.Raw}
  309. var sctList []ct.SignedCertificateTimestamp
  310. for _, server := range profile.CTLogServers {
  311. log.Infof("submitting poisoned precertificate to %s", server)
  312. var ctclient = client.New(server, nil)
  313. var resp *ct.SignedCertificateTimestamp
  314. resp, err = ctclient.AddPreChain(prechain)
  315. if err != nil {
  316. return nil, cferr.Wrap(cferr.CTError, cferr.PrecertSubmissionFailed, err)
  317. }
  318. sctList = append(sctList, *resp)
  319. }
  320. var serializedSCTList []byte
  321. serializedSCTList, err = serializeSCTList(sctList)
  322. if err != nil {
  323. return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err)
  324. }
  325. // Serialize again as an octet string before embedding
  326. serializedSCTList, err = asn1.Marshal(serializedSCTList)
  327. if err != nil {
  328. return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err)
  329. }
  330. var SCTListExtension = pkix.Extension{Id: signer.SCTListOID, Critical: false, Value: serializedSCTList}
  331. certTBS.ExtraExtensions = append(certTBS.ExtraExtensions, SCTListExtension)
  332. }
  333. var signedCert []byte
  334. signedCert, err = s.sign(&certTBS, profile)
  335. if err != nil {
  336. return nil, err
  337. }
  338. if s.dbAccessor != nil {
  339. var certRecord = certdb.CertificateRecord{
  340. Serial: certTBS.SerialNumber.String(),
  341. // this relies on the specific behavior of x509.CreateCertificate
  342. // which updates certTBS AuthorityKeyId from the signer's SubjectKeyId
  343. AKI: hex.EncodeToString(certTBS.AuthorityKeyId),
  344. CALabel: req.Label,
  345. Status: "good",
  346. Expiry: certTBS.NotAfter,
  347. PEM: string(signedCert),
  348. }
  349. err = s.dbAccessor.InsertCertificate(certRecord)
  350. if err != nil {
  351. return nil, err
  352. }
  353. log.Debug("saved certificate with serial number ", certTBS.SerialNumber)
  354. }
  355. return signedCert, nil
  356. }
  357. func serializeSCTList(sctList []ct.SignedCertificateTimestamp) ([]byte, error) {
  358. var buf bytes.Buffer
  359. for _, sct := range sctList {
  360. sct, err := ct.SerializeSCT(sct)
  361. if err != nil {
  362. return nil, err
  363. }
  364. binary.Write(&buf, binary.BigEndian, uint16(len(sct)))
  365. buf.Write(sct)
  366. }
  367. var sctListLengthField = make([]byte, 2)
  368. binary.BigEndian.PutUint16(sctListLengthField, uint16(buf.Len()))
  369. return bytes.Join([][]byte{sctListLengthField, buf.Bytes()}, nil), nil
  370. }
  371. // Info return a populated info.Resp struct or an error.
  372. func (s *Signer) Info(req info.Req) (resp *info.Resp, err error) {
  373. cert, err := s.Certificate(req.Label, req.Profile)
  374. if err != nil {
  375. return
  376. }
  377. profile, err := signer.Profile(s, req.Profile)
  378. if err != nil {
  379. return
  380. }
  381. resp = new(info.Resp)
  382. if cert.Raw != nil {
  383. resp.Certificate = string(bytes.TrimSpace(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})))
  384. }
  385. resp.Usage = profile.Usage
  386. resp.ExpiryString = profile.ExpiryString
  387. return
  388. }
  389. // SigAlgo returns the RSA signer's signature algorithm.
  390. func (s *Signer) SigAlgo() x509.SignatureAlgorithm {
  391. return s.sigAlgo
  392. }
  393. // Certificate returns the signer's certificate.
  394. func (s *Signer) Certificate(label, profile string) (*x509.Certificate, error) {
  395. cert := *s.ca
  396. return &cert, nil
  397. }
  398. // SetPolicy sets the signer's signature policy.
  399. func (s *Signer) SetPolicy(policy *config.Signing) {
  400. s.policy = policy
  401. }
  402. // SetDBAccessor sets the signers' cert db accessor
  403. func (s *Signer) SetDBAccessor(dba certdb.Accessor) {
  404. s.dbAccessor = dba
  405. }
  406. // Policy returns the signer's policy.
  407. func (s *Signer) Policy() *config.Signing {
  408. return s.policy
  409. }