chain.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Copyright 2017 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. "bytes"
  7. "strings"
  8. )
  9. // CertificateChain is a slice of certificates. The 0'th element is the leaf,
  10. // and the last element is a root. Successive elements have a child-parent
  11. // relationship.
  12. type CertificateChain []*Certificate
  13. // Range runs a function on each element of chain. It can modify each
  14. // certificate in place.
  15. func (chain CertificateChain) Range(f func(int, *Certificate)) {
  16. for i, c := range chain {
  17. f(i, c)
  18. }
  19. }
  20. // SubjectAndKeyInChain returns true if the given SubjectAndKey is found in any
  21. // certificate in the chain.
  22. func (chain CertificateChain) SubjectAndKeyInChain(sk *SubjectAndKey) bool {
  23. for _, cert := range chain {
  24. if bytes.Equal(sk.RawSubject, cert.RawSubject) && bytes.Equal(sk.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) {
  25. return true
  26. }
  27. }
  28. return false
  29. }
  30. // CertificateSubjectAndKeyInChain returns true if the SubjectAndKey from c is
  31. // found in any certificate in the chain.
  32. func (chain CertificateChain) CertificateSubjectAndKeyInChain(c *Certificate) bool {
  33. for _, cert := range chain {
  34. if bytes.Equal(c.RawSubject, cert.RawSubject) && bytes.Equal(c.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) {
  35. return true
  36. }
  37. }
  38. return false
  39. }
  40. // CertificateInChain returns true if c is in the chain.
  41. func (chain CertificateChain) CertificateInChain(c *Certificate) bool {
  42. for _, cert := range chain {
  43. if bytes.Equal(c.Raw, cert.Raw) {
  44. return true
  45. }
  46. }
  47. return false
  48. }
  49. func (chain CertificateChain) AppendToFreshChain(c *Certificate) CertificateChain {
  50. n := make([]*Certificate, len(chain)+1)
  51. copy(n, chain)
  52. n[len(chain)] = c
  53. return n
  54. }
  55. func (chain CertificateChain) chainID() string {
  56. var parts []string
  57. for _, c := range chain {
  58. parts = append(parts, string(c.FingerprintSHA256))
  59. }
  60. return strings.Join(parts, "")
  61. }