cipher_util.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package s3crypto
  2. import (
  3. "encoding/base64"
  4. "strconv"
  5. "github.com/aws/aws-sdk-go/aws/awserr"
  6. )
  7. func (client *DecryptionClient) contentCipherFromEnvelope(env Envelope) (ContentCipher, error) {
  8. wrap, err := client.wrapFromEnvelope(env)
  9. if err != nil {
  10. return nil, err
  11. }
  12. return client.cekFromEnvelope(env, wrap)
  13. }
  14. func (client *DecryptionClient) wrapFromEnvelope(env Envelope) (CipherDataDecrypter, error) {
  15. f, ok := client.WrapRegistry[env.WrapAlg]
  16. if !ok || f == nil {
  17. return nil, awserr.New(
  18. "InvalidWrapAlgorithmError",
  19. "wrap algorithm isn't supported, "+env.WrapAlg,
  20. nil,
  21. )
  22. }
  23. return f(env)
  24. }
  25. // AESGCMNoPadding is the constant value that is used to specify
  26. // the CEK algorithm consiting of AES GCM with no padding.
  27. const AESGCMNoPadding = "AES/GCM/NoPadding"
  28. func (client *DecryptionClient) cekFromEnvelope(env Envelope, decrypter CipherDataDecrypter) (ContentCipher, error) {
  29. f, ok := client.CEKRegistry[env.CEKAlg]
  30. if !ok || f == nil {
  31. return nil, awserr.New(
  32. "InvalidCEKAlgorithmError",
  33. "cek algorithm isn't supported, "+env.CEKAlg,
  34. nil,
  35. )
  36. }
  37. key, err := base64.StdEncoding.DecodeString(env.CipherKey)
  38. if err != nil {
  39. return nil, err
  40. }
  41. iv, err := base64.StdEncoding.DecodeString(env.IV)
  42. if err != nil {
  43. return nil, err
  44. }
  45. key, err = decrypter.DecryptKey(key)
  46. if err != nil {
  47. return nil, err
  48. }
  49. cd := CipherData{
  50. Key: key,
  51. IV: iv,
  52. }
  53. return f(cd)
  54. }
  55. func encodeMeta(reader hashReader, cd CipherData) (Envelope, error) {
  56. iv := base64.StdEncoding.EncodeToString(cd.IV)
  57. key := base64.StdEncoding.EncodeToString(cd.EncryptedKey)
  58. md5 := reader.GetValue()
  59. contentLength := reader.GetContentLength()
  60. md5Str := base64.StdEncoding.EncodeToString(md5)
  61. matdesc, err := cd.MaterialDescription.encodeDescription()
  62. if err != nil {
  63. return Envelope{}, err
  64. }
  65. return Envelope{
  66. CipherKey: key,
  67. IV: iv,
  68. MatDesc: string(matdesc),
  69. WrapAlg: cd.WrapAlgorithm,
  70. CEKAlg: cd.CEKAlgorithm,
  71. TagLen: cd.TagLength,
  72. UnencryptedMD5: md5Str,
  73. UnencryptedContentLen: strconv.FormatInt(contentLength, 10),
  74. }, nil
  75. }