cert.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package cert
  2. import (
  3. "crypto/rand"
  4. "crypto/rsa"
  5. "crypto/x509"
  6. "encoding/pem"
  7. "math/big"
  8. "time"
  9. "v2ray.com/core/common"
  10. )
  11. //go:generate errorgen
  12. type Certificate struct {
  13. // Cerificate in ASN.1 DER format
  14. Certificate []byte
  15. // Private key in ASN.1 DER format
  16. PrivateKey []byte
  17. }
  18. func ParseCertificate(certPEM []byte, keyPEM []byte) (*Certificate, error) {
  19. certBlock, _ := pem.Decode(certPEM)
  20. if certBlock == nil {
  21. return nil, newError("failed to decode certificate")
  22. }
  23. keyBlock, _ := pem.Decode(keyPEM)
  24. if keyBlock == nil {
  25. return nil, newError("failed to decode key")
  26. }
  27. return &Certificate{
  28. Certificate: certBlock.Bytes,
  29. PrivateKey: keyBlock.Bytes,
  30. }, nil
  31. }
  32. func (c *Certificate) ToPEM() ([]byte, []byte) {
  33. return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: c.Certificate}),
  34. pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: c.PrivateKey})
  35. }
  36. type Option func(*x509.Certificate)
  37. func Authority(isCA bool) Option {
  38. return func(cert *x509.Certificate) {
  39. cert.IsCA = isCA
  40. }
  41. }
  42. func NotBefore(t time.Time) Option {
  43. return func(c *x509.Certificate) {
  44. c.NotBefore = t
  45. }
  46. }
  47. func NotAfter(t time.Time) Option {
  48. return func(c *x509.Certificate) {
  49. c.NotAfter = t
  50. }
  51. }
  52. func DNSNames(names ...string) Option {
  53. return func(c *x509.Certificate) {
  54. c.DNSNames = names
  55. }
  56. }
  57. func CommonName(name string) Option {
  58. return func(c *x509.Certificate) {
  59. c.Subject.CommonName = name
  60. }
  61. }
  62. func KeyUsage(usage x509.KeyUsage) Option {
  63. return func(c *x509.Certificate) {
  64. c.KeyUsage = usage
  65. }
  66. }
  67. func Organization(org string) Option {
  68. return func(c *x509.Certificate) {
  69. c.Subject.Organization = []string{org}
  70. }
  71. }
  72. func MustGenerate(parent *Certificate, opts ...Option) *Certificate {
  73. cert, err := Generate(parent, opts...)
  74. common.Must(err)
  75. return cert
  76. }
  77. func Generate(parent *Certificate, opts ...Option) (*Certificate, error) {
  78. selfKey, err := rsa.GenerateKey(rand.Reader, 2048)
  79. if err != nil {
  80. return nil, newError("failed to generate self private key").Base(err)
  81. }
  82. parentKey := selfKey
  83. if parent != nil {
  84. pKey, err := x509.ParsePKCS1PrivateKey(parent.PrivateKey)
  85. if err != nil {
  86. return nil, newError("failed to parse parent private key").Base(err)
  87. }
  88. parentKey = pKey
  89. }
  90. serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
  91. serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
  92. if err != nil {
  93. return nil, newError("failed to generate serial number").Base(err)
  94. }
  95. template := &x509.Certificate{
  96. SerialNumber: serialNumber,
  97. NotBefore: time.Now().Add(time.Hour * -1),
  98. NotAfter: time.Now().Add(time.Hour),
  99. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
  100. ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
  101. BasicConstraintsValid: true,
  102. }
  103. for _, opt := range opts {
  104. opt(template)
  105. }
  106. parentCert := template
  107. if parent != nil {
  108. pCert, err := x509.ParseCertificate(parent.Certificate)
  109. if err != nil {
  110. return nil, newError("failed to parse parent certificate").Base(err)
  111. }
  112. parentCert = pCert
  113. }
  114. derBytes, err := x509.CreateCertificate(rand.Reader, template, parentCert, selfKey.Public(), parentKey)
  115. if err != nil {
  116. return nil, newError("failed to create certificate").Base(err)
  117. }
  118. return &Certificate{
  119. Certificate: derBytes,
  120. PrivateKey: x509.MarshalPKCS1PrivateKey(selfKey),
  121. }, nil
  122. }