cert.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Copyright 2015 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 main
  5. import (
  6. "crypto"
  7. "crypto/rsa"
  8. "crypto/sha1"
  9. "crypto/x509"
  10. "crypto/x509/pkix"
  11. "encoding/asn1"
  12. "io"
  13. "math/big"
  14. "time"
  15. )
  16. // signPKCS7 does the minimal amount of work necessary to embed an RSA
  17. // signature into a PKCS#7 certificate.
  18. //
  19. // We prepare the certificate using the x509 package, read it back in
  20. // to our custom data type and then write it back out with the signature.
  21. func signPKCS7(rand io.Reader, priv *rsa.PrivateKey, msg []byte) ([]byte, error) {
  22. const serialNumber = 0x5462c4dd // arbitrary
  23. name := pkix.Name{CommonName: "gomobile"}
  24. template := &x509.Certificate{
  25. SerialNumber: big.NewInt(serialNumber),
  26. SignatureAlgorithm: x509.SHA1WithRSA,
  27. Subject: name,
  28. }
  29. b, err := x509.CreateCertificate(rand, template, template, priv.Public(), priv)
  30. if err != nil {
  31. return nil, err
  32. }
  33. c := certificate{}
  34. if _, err := asn1.Unmarshal(b, &c); err != nil {
  35. return nil, err
  36. }
  37. h := sha1.New()
  38. h.Write(msg)
  39. hashed := h.Sum(nil)
  40. signed, err := rsa.SignPKCS1v15(rand, priv, crypto.SHA1, hashed)
  41. if err != nil {
  42. return nil, err
  43. }
  44. content := pkcs7SignedData{
  45. ContentType: oidSignedData,
  46. Content: signedData{
  47. Version: 1,
  48. DigestAlgorithms: []pkix.AlgorithmIdentifier{{
  49. Algorithm: oidSHA1,
  50. Parameters: asn1.RawValue{Tag: 5},
  51. }},
  52. ContentInfo: contentInfo{Type: oidData},
  53. Certificates: c,
  54. SignerInfos: []signerInfo{{
  55. Version: 1,
  56. IssuerAndSerialNumber: issuerAndSerialNumber{
  57. Issuer: name.ToRDNSequence(),
  58. SerialNumber: serialNumber,
  59. },
  60. DigestAlgorithm: pkix.AlgorithmIdentifier{
  61. Algorithm: oidSHA1,
  62. Parameters: asn1.RawValue{Tag: 5},
  63. },
  64. DigestEncryptionAlgorithm: pkix.AlgorithmIdentifier{
  65. Algorithm: oidRSAEncryption,
  66. Parameters: asn1.RawValue{Tag: 5},
  67. },
  68. EncryptedDigest: signed,
  69. }},
  70. },
  71. }
  72. return asn1.Marshal(content)
  73. }
  74. type pkcs7SignedData struct {
  75. ContentType asn1.ObjectIdentifier
  76. Content signedData `asn1:"tag:0,explicit"`
  77. }
  78. // signedData is defined in rfc2315, section 9.1.
  79. type signedData struct {
  80. Version int
  81. DigestAlgorithms []pkix.AlgorithmIdentifier `asn1:"set"`
  82. ContentInfo contentInfo
  83. Certificates certificate `asn1:"tag0,explicit"`
  84. SignerInfos []signerInfo `asn1:"set"`
  85. }
  86. type contentInfo struct {
  87. Type asn1.ObjectIdentifier
  88. // Content is optional in PKCS#7 and not provided here.
  89. }
  90. // certificate is defined in rfc2459, section 4.1.
  91. type certificate struct {
  92. TBSCertificate tbsCertificate
  93. SignatureAlgorithm pkix.AlgorithmIdentifier
  94. SignatureValue asn1.BitString
  95. }
  96. // tbsCertificate is defined in rfc2459, section 4.1.
  97. type tbsCertificate struct {
  98. Version int `asn1:"tag:0,default:2,explicit"`
  99. SerialNumber int
  100. Signature pkix.AlgorithmIdentifier
  101. Issuer pkix.RDNSequence // pkix.Name
  102. Validity validity
  103. Subject pkix.RDNSequence // pkix.Name
  104. SubjectPKI subjectPublicKeyInfo
  105. }
  106. // validity is defined in rfc2459, section 4.1.
  107. type validity struct {
  108. NotBefore time.Time
  109. NotAfter time.Time
  110. }
  111. // subjectPublicKeyInfo is defined in rfc2459, section 4.1.
  112. type subjectPublicKeyInfo struct {
  113. Algorithm pkix.AlgorithmIdentifier
  114. SubjectPublicKey asn1.BitString
  115. }
  116. type signerInfo struct {
  117. Version int
  118. IssuerAndSerialNumber issuerAndSerialNumber
  119. DigestAlgorithm pkix.AlgorithmIdentifier
  120. DigestEncryptionAlgorithm pkix.AlgorithmIdentifier
  121. EncryptedDigest []byte
  122. }
  123. type issuerAndSerialNumber struct {
  124. Issuer pkix.RDNSequence // pkix.Name
  125. SerialNumber int
  126. }
  127. // Various ASN.1 Object Identifies, mostly from rfc3852.
  128. var (
  129. oidPKCS7 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7}
  130. oidData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1}
  131. oidSignedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 2}
  132. oidSHA1 = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26}
  133. oidRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
  134. )