decrypt.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package xmlenc
  2. import (
  3. // nolint: gas
  4. "crypto/rsa"
  5. "crypto/x509"
  6. "encoding/base64"
  7. "encoding/pem"
  8. "errors"
  9. "fmt"
  10. "strings"
  11. "github.com/beevik/etree"
  12. )
  13. // ErrAlgorithmNotImplemented is returned when encryption used is not
  14. // supported.
  15. type ErrAlgorithmNotImplemented string
  16. func (e ErrAlgorithmNotImplemented) Error() string {
  17. return "algorithm is not implemented: " + string(e)
  18. }
  19. // ErrCannotFindRequiredElement is returned by Decrypt when a required
  20. // element cannot be found.
  21. type ErrCannotFindRequiredElement string
  22. func (e ErrCannotFindRequiredElement) Error() string {
  23. return "cannot find required element: " + string(e)
  24. }
  25. // ErrIncorrectTag is returned when Decrypt is passed an element which
  26. // is neither an EncryptedType nor an EncryptedKey
  27. var ErrIncorrectTag = fmt.Errorf("tag must be an EncryptedType or EncryptedKey")
  28. // ErrIncorrectKeyLength is returned when the fixed length key is not
  29. // of the required length.
  30. type ErrIncorrectKeyLength int
  31. func (e ErrIncorrectKeyLength) Error() string {
  32. return fmt.Sprintf("expected key to be %d bytes", int(e))
  33. }
  34. // ErrIncorrectKeyType is returned when the key is not the correct type
  35. type ErrIncorrectKeyType string
  36. func (e ErrIncorrectKeyType) Error() string {
  37. return fmt.Sprintf("expected key to be %s", string(e))
  38. }
  39. // Decrypt decrypts the encrypted data using the provided key. If the
  40. // data are encrypted using AES or 3DEC, then the key should be a []byte.
  41. // If the data are encrypted with PKCS1v15 or RSA-OAEP-MGF1P then key should
  42. // be a *rsa.PrivateKey.
  43. func Decrypt(key interface{}, ciphertextEl *etree.Element) ([]byte, error) {
  44. encryptionMethodEl := ciphertextEl.FindElement("./EncryptionMethod")
  45. if encryptionMethodEl == nil {
  46. return nil, ErrCannotFindRequiredElement("EncryptionMethod")
  47. }
  48. algorithm := encryptionMethodEl.SelectAttrValue("Algorithm", "")
  49. decrypter, ok := decrypters[algorithm]
  50. if !ok {
  51. return nil, ErrAlgorithmNotImplemented(algorithm)
  52. }
  53. return decrypter.Decrypt(key, ciphertextEl)
  54. }
  55. func getCiphertext(encryptedKey *etree.Element) ([]byte, error) {
  56. ciphertextEl := encryptedKey.FindElement("./CipherData/CipherValue")
  57. if ciphertextEl == nil {
  58. return nil, fmt.Errorf("cannot find CipherData element containing a CipherValue element")
  59. }
  60. ciphertext, err := base64.StdEncoding.DecodeString(strings.TrimSpace(ciphertextEl.Text()))
  61. if err != nil {
  62. return nil, err
  63. }
  64. return ciphertext, nil
  65. }
  66. func validateRSAKey(key interface{}, encryptedKey *etree.Element) (*rsa.PrivateKey, error) {
  67. rsaKey, ok := key.(*rsa.PrivateKey)
  68. if !ok {
  69. return nil, errors.New("expected key to be a *rsa.PrivateKey")
  70. }
  71. // extract and verify that the public key matches the certificate
  72. // this section is included to either let the service know up front
  73. // if the key will work, or let the service provider know which key
  74. // to use to decrypt the message. Either way, verification is not
  75. // security-critical.
  76. if el := encryptedKey.FindElement("./KeyInfo/X509Data/X509Certificate"); el != nil {
  77. certPEMbuf := el.Text()
  78. certPEMbuf = "-----BEGIN CERTIFICATE-----\n" + certPEMbuf + "\n-----END CERTIFICATE-----\n"
  79. certPEM, _ := pem.Decode([]byte(certPEMbuf))
  80. if certPEM == nil {
  81. return nil, fmt.Errorf("invalid certificate")
  82. }
  83. cert, err := x509.ParseCertificate(certPEM.Bytes)
  84. if err != nil {
  85. return nil, err
  86. }
  87. pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
  88. if !ok {
  89. return nil, fmt.Errorf("expected certificate to be an *rsa.PublicKey")
  90. }
  91. if rsaKey.N.Cmp(pubKey.N) != 0 || rsaKey.E != pubKey.E {
  92. return nil, fmt.Errorf("certificate does not match provided key")
  93. }
  94. } else if el = encryptedKey.FindElement("./KeyInfo/X509Data/X509IssuerSerial"); el != nil {
  95. // TODO: determine how to validate the issuer serial information
  96. } else {
  97. return nil, ErrCannotFindRequiredElement("X509Certificate or X509IssuerSerial")
  98. }
  99. return rsaKey, nil
  100. }