crypto.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package dtls
  4. import (
  5. "crypto"
  6. "crypto/ecdsa"
  7. "crypto/ed25519"
  8. "crypto/rand"
  9. "crypto/rsa"
  10. "crypto/sha256"
  11. "crypto/x509"
  12. "encoding/asn1"
  13. "encoding/binary"
  14. "math/big"
  15. "time"
  16. "github.com/pion/dtls/v2/pkg/crypto/elliptic"
  17. "github.com/pion/dtls/v2/pkg/crypto/hash"
  18. )
  19. type ecdsaSignature struct {
  20. R, S *big.Int
  21. }
  22. func valueKeyMessage(clientRandom, serverRandom, publicKey []byte, namedCurve elliptic.Curve) []byte {
  23. serverECDHParams := make([]byte, 4)
  24. serverECDHParams[0] = 3 // named curve
  25. binary.BigEndian.PutUint16(serverECDHParams[1:], uint16(namedCurve))
  26. serverECDHParams[3] = byte(len(publicKey))
  27. plaintext := []byte{}
  28. plaintext = append(plaintext, clientRandom...)
  29. plaintext = append(plaintext, serverRandom...)
  30. plaintext = append(plaintext, serverECDHParams...)
  31. plaintext = append(plaintext, publicKey...)
  32. return plaintext
  33. }
  34. // If the client provided a "signature_algorithms" extension, then all
  35. // certificates provided by the server MUST be signed by a
  36. // hash/signature algorithm pair that appears in that extension
  37. //
  38. // https://tools.ietf.org/html/rfc5246#section-7.4.2
  39. func generateKeySignature(clientRandom, serverRandom, publicKey []byte, namedCurve elliptic.Curve, privateKey crypto.PrivateKey, hashAlgorithm hash.Algorithm) ([]byte, error) {
  40. msg := valueKeyMessage(clientRandom, serverRandom, publicKey, namedCurve)
  41. switch p := privateKey.(type) {
  42. case ed25519.PrivateKey:
  43. // https://crypto.stackexchange.com/a/55483
  44. return p.Sign(rand.Reader, msg, crypto.Hash(0))
  45. case *ecdsa.PrivateKey:
  46. hashed := hashAlgorithm.Digest(msg)
  47. return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash())
  48. case *rsa.PrivateKey:
  49. hashed := hashAlgorithm.Digest(msg)
  50. return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash())
  51. }
  52. return nil, errKeySignatureGenerateUnimplemented
  53. }
  54. func verifyKeySignature(message, remoteKeySignature []byte, hashAlgorithm hash.Algorithm, rawCertificates [][]byte) error { //nolint:dupl
  55. if len(rawCertificates) == 0 {
  56. return errLengthMismatch
  57. }
  58. certificate, err := x509.ParseCertificate(rawCertificates[0])
  59. if err != nil {
  60. return err
  61. }
  62. switch p := certificate.PublicKey.(type) {
  63. case ed25519.PublicKey:
  64. if ok := ed25519.Verify(p, message, remoteKeySignature); !ok {
  65. return errKeySignatureMismatch
  66. }
  67. return nil
  68. case *ecdsa.PublicKey:
  69. ecdsaSig := &ecdsaSignature{}
  70. if _, err := asn1.Unmarshal(remoteKeySignature, ecdsaSig); err != nil {
  71. return err
  72. }
  73. if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
  74. return errInvalidECDSASignature
  75. }
  76. hashed := hashAlgorithm.Digest(message)
  77. if !ecdsa.Verify(p, hashed, ecdsaSig.R, ecdsaSig.S) {
  78. return errKeySignatureMismatch
  79. }
  80. return nil
  81. case *rsa.PublicKey:
  82. switch certificate.SignatureAlgorithm {
  83. case x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA:
  84. hashed := hashAlgorithm.Digest(message)
  85. return rsa.VerifyPKCS1v15(p, hashAlgorithm.CryptoHash(), hashed, remoteKeySignature)
  86. default:
  87. return errKeySignatureVerifyUnimplemented
  88. }
  89. }
  90. return errKeySignatureVerifyUnimplemented
  91. }
  92. // If the server has sent a CertificateRequest message, the client MUST send the Certificate
  93. // message. The ClientKeyExchange message is now sent, and the content
  94. // of that message will depend on the public key algorithm selected
  95. // between the ClientHello and the ServerHello. If the client has sent
  96. // a certificate with signing ability, a digitally-signed
  97. // CertificateVerify message is sent to explicitly verify possession of
  98. // the private key in the certificate.
  99. // https://tools.ietf.org/html/rfc5246#section-7.3
  100. func generateCertificateVerify(handshakeBodies []byte, privateKey crypto.PrivateKey, hashAlgorithm hash.Algorithm) ([]byte, error) {
  101. if p, ok := privateKey.(ed25519.PrivateKey); ok {
  102. // https://pkg.go.dev/crypto/ed25519#PrivateKey.Sign
  103. // Sign signs the given message with priv. Ed25519 performs two passes over
  104. // messages to be signed and therefore cannot handle pre-hashed messages.
  105. return p.Sign(rand.Reader, handshakeBodies, crypto.Hash(0))
  106. }
  107. h := sha256.New()
  108. if _, err := h.Write(handshakeBodies); err != nil {
  109. return nil, err
  110. }
  111. hashed := h.Sum(nil)
  112. switch p := privateKey.(type) {
  113. case *ecdsa.PrivateKey:
  114. return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash())
  115. case *rsa.PrivateKey:
  116. return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash())
  117. }
  118. return nil, errInvalidSignatureAlgorithm
  119. }
  120. func verifyCertificateVerify(handshakeBodies []byte, hashAlgorithm hash.Algorithm, remoteKeySignature []byte, rawCertificates [][]byte) error { //nolint:dupl
  121. if len(rawCertificates) == 0 {
  122. return errLengthMismatch
  123. }
  124. certificate, err := x509.ParseCertificate(rawCertificates[0])
  125. if err != nil {
  126. return err
  127. }
  128. switch p := certificate.PublicKey.(type) {
  129. case ed25519.PublicKey:
  130. if ok := ed25519.Verify(p, handshakeBodies, remoteKeySignature); !ok {
  131. return errKeySignatureMismatch
  132. }
  133. return nil
  134. case *ecdsa.PublicKey:
  135. ecdsaSig := &ecdsaSignature{}
  136. if _, err := asn1.Unmarshal(remoteKeySignature, ecdsaSig); err != nil {
  137. return err
  138. }
  139. if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
  140. return errInvalidECDSASignature
  141. }
  142. hash := hashAlgorithm.Digest(handshakeBodies)
  143. if !ecdsa.Verify(p, hash, ecdsaSig.R, ecdsaSig.S) {
  144. return errKeySignatureMismatch
  145. }
  146. return nil
  147. case *rsa.PublicKey:
  148. switch certificate.SignatureAlgorithm {
  149. case x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA:
  150. hash := hashAlgorithm.Digest(handshakeBodies)
  151. return rsa.VerifyPKCS1v15(p, hashAlgorithm.CryptoHash(), hash, remoteKeySignature)
  152. default:
  153. return errKeySignatureVerifyUnimplemented
  154. }
  155. }
  156. return errKeySignatureVerifyUnimplemented
  157. }
  158. func loadCerts(rawCertificates [][]byte) ([]*x509.Certificate, error) {
  159. if len(rawCertificates) == 0 {
  160. return nil, errLengthMismatch
  161. }
  162. certs := make([]*x509.Certificate, 0, len(rawCertificates))
  163. for _, rawCert := range rawCertificates {
  164. cert, err := x509.ParseCertificate(rawCert)
  165. if err != nil {
  166. return nil, err
  167. }
  168. certs = append(certs, cert)
  169. }
  170. return certs, nil
  171. }
  172. func verifyClientCert(rawCertificates [][]byte, roots *x509.CertPool) (chains [][]*x509.Certificate, err error) {
  173. certificate, err := loadCerts(rawCertificates)
  174. if err != nil {
  175. return nil, err
  176. }
  177. intermediateCAPool := x509.NewCertPool()
  178. for _, cert := range certificate[1:] {
  179. intermediateCAPool.AddCert(cert)
  180. }
  181. opts := x509.VerifyOptions{
  182. Roots: roots,
  183. CurrentTime: time.Now(),
  184. Intermediates: intermediateCAPool,
  185. KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
  186. }
  187. return certificate[0].Verify(opts)
  188. }
  189. func verifyServerCert(rawCertificates [][]byte, roots *x509.CertPool, serverName string) (chains [][]*x509.Certificate, err error) {
  190. certificate, err := loadCerts(rawCertificates)
  191. if err != nil {
  192. return nil, err
  193. }
  194. intermediateCAPool := x509.NewCertPool()
  195. for _, cert := range certificate[1:] {
  196. intermediateCAPool.AddCert(cert)
  197. }
  198. opts := x509.VerifyOptions{
  199. Roots: roots,
  200. CurrentTime: time.Now(),
  201. DNSName: serverName,
  202. Intermediates: intermediateCAPool,
  203. }
  204. return certificate[0].Verify(opts)
  205. }