github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/saltpack_dec.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package libkb 5 6 import ( 7 "io" 8 9 "github.com/keybase/saltpack" 10 ) 11 12 func getStatusCodeFromDecryptionError(err *DecryptionError) (code int) { 13 switch err.Cause.Err.(type) { 14 case APINetError: 15 code = SCAPINetworkError 16 case saltpack.ErrNoSenderKey: 17 code = SCDecryptionKeyNotFound 18 case saltpack.ErrWrongMessageType: 19 code = SCWrongCryptoMsgType 20 } 21 return code 22 } 23 24 func SaltpackDecrypt(m MetaContext, source io.Reader, sink io.WriteCloser, 25 decryptionKeyring saltpack.SigncryptKeyring, 26 checkSenderMki func(*saltpack.MessageKeyInfo) error, 27 checkSenderSigningKey func(saltpack.SigningPublicKey) error, 28 keyResolver saltpack.SymmetricKeyResolver) (mki *saltpack.MessageKeyInfo, err error) { 29 defer func() { 30 if derr, ok := err.(DecryptionError); ok { 31 derr.Cause.StatusCode = getStatusCodeFromDecryptionError(&derr) 32 err = derr 33 } 34 }() 35 36 sc, newSource, err := ClassifyStream(source) 37 if err != nil { 38 return nil, err 39 } 40 41 if sc.Format != CryptoMessageFormatSaltpack { 42 return nil, WrongCryptoFormatError{ 43 Wanted: CryptoMessageFormatSaltpack, 44 Received: sc.Format, 45 Operation: "decrypt", 46 } 47 } 48 49 source = newSource 50 51 // mki will be set for DH mode, senderSigningKey will be set for signcryption mode 52 plainsource, typ, mki, senderSigningKey, isArmored, brand, _, err := saltpack.ClassifyEncryptedStreamAndMakeDecoder(source, decryptionKeyring, keyResolver) 53 if err != nil { 54 return mki, DecryptionError{Cause: ErrorCause{Err: err}} 55 } 56 57 if typ == saltpack.MessageTypeEncryption && checkSenderMki != nil { 58 if err = checkSenderMki(mki); err != nil { 59 return mki, DecryptionError{Cause: ErrorCause{Err: err}} 60 } 61 } 62 if typ == saltpack.MessageTypeSigncryption && checkSenderSigningKey != nil { 63 if err = checkSenderSigningKey(senderSigningKey); err != nil { 64 return nil, DecryptionError{Cause: ErrorCause{Err: err}} 65 } 66 } 67 68 n, err := io.Copy(sink, plainsource) 69 if err != nil { 70 return mki, DecryptionError{Cause: ErrorCause{Err: err}} 71 } 72 73 if isArmored { 74 // Note: the following check always passes! 75 if err = checkSaltpackBrand(brand); err != nil { 76 return mki, DecryptionError{Cause: ErrorCause{Err: err}} 77 } 78 } 79 80 m.Debug("Decrypt: read %d bytes", n) 81 82 if err := sink.Close(); err != nil { 83 return mki, DecryptionError{Cause: ErrorCause{Err: err}} 84 } 85 return mki, nil 86 }