Skip to content

Commit fb36cb6

Browse files
committed
Convert strings to binaries even if disabled or secret pending
This way the type signature does not depend on the service state and is consistenly: `decrypt(encrypt(Data)) -> binary()`. Some users like rabbit_shovel_parameters rely on this (https://github.com/rabbitmq/rabbitmq-server/blob/master/deps/rabbitmq_shovel/src/rabbit_shovel_parameters.erl#L447)
1 parent 681758c commit fb36cb6

File tree

5 files changed

+30
-13
lines changed

5 files changed

+30
-13
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ credentials_obfuscation:decrypt(Encrypted).
4444
```
4545

4646
Lists (char lists in Elixir) will be converted to binaries before encryption.
47-
This means that decrypted values will also be returned as binaries.
47+
This means that decrypted values will alwyas be returned as binaries.
48+
49+
(Lists hear mean "byte lists" that is unicode characters are not
50+
supported. But that should be no problem for encrypting for example
51+
URIs.)
4852

4953
## License and Copyright
5054

src/credentials_obfuscation.erl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,15 @@ set_secret(Secret) when is_binary(Secret) ->
4242
set_fallback_secret(Secret) when is_binary(Secret) ->
4343
ok = credentials_obfuscation_svc:set_fallback_secret(Secret).
4444

45-
-spec encrypt(term()) -> {plaintext, term()} | {encrypted, binary()}.
45+
-spec encrypt(none | undefined) -> none | undefined;
46+
(iodata()) -> {plaintext, binary()} | {encrypted, binary()}.
4647
encrypt(none) -> none;
4748
encrypt(undefined) -> undefined;
4849
encrypt(Term) ->
4950
credentials_obfuscation_svc:encrypt(Term).
5051

51-
-spec decrypt({plaintext, term()} | {encrypted, binary()}) -> term().
52+
-spec decrypt(none | undefined) -> none | undefined;
53+
({plaintext, binary()} | {encrypted, binary()}) -> binary().
5254
decrypt(none) -> none;
5355
decrypt(undefined) -> undefined;
5456
decrypt(Term) ->

src/credentials_obfuscation_pbe.erl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ decrypt_term(Cipher, Hash, Iterations, Secret, Base64Binary) ->
6565
%% function accepts that same base64 binary.
6666

6767
-spec encrypt(crypto:cipher_iv(), crypto:hash_algorithm(),
68-
pos_integer(), iodata() | '$pending-secret', binary()) -> {plaintext, binary()} | {encrypted, binary()}.
68+
pos_integer(), iodata() | '$pending-secret', iodata()) -> {plaintext, binary()} | {encrypted, binary()}.
6969
encrypt(_Cipher, _Hash, _Iterations, ?PENDING_SECRET, ClearText) ->
70-
{plaintext, ClearText};
70+
{plaintext, iolist_to_binary(ClearText)};
7171
encrypt(Cipher, Hash, Iterations, Secret, ClearText) when is_list(ClearText) ->
7272
encrypt(Cipher, Hash, Iterations, Secret, list_to_binary(ClearText));
7373
encrypt(Cipher, Hash, Iterations, Secret, ClearText) when is_binary(ClearText) ->

src/credentials_obfuscation_svc.erl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ set_fallback_secret(Secret) when is_binary(Secret) ->
6262
gen_server:call(?MODULE, {set_fallback_secret, Secret}).
6363

6464

65-
-spec encrypt(term()) -> {plaintext, term()} | {encrypted, binary()}.
65+
-spec encrypt(iodata()) -> {plaintext, binary()} | {encrypted, binary()} | binary().
6666
encrypt(Term) when is_binary(Term); is_list(Term) ->
6767
try
6868
gen_server:call(?MODULE, {encrypt, Term}, ?TIMEOUT)
@@ -72,13 +72,13 @@ encrypt(Term) when is_binary(Term); is_list(Term) ->
7272
%% but might be to some. There is no right or wrong answer to whether
7373
%% availability or security are more important, so the users have to decide
7474
%% whether using {plaintext, Term} results is appropriate in their specific case.
75-
{plaintext, Term};
75+
{plaintext, to_binary(Term)};
7676
_:_ ->
7777
%% see above
78-
{plaintext, Term}
78+
{plaintext, to_binary(Term)}
7979
end.
8080

81-
-spec decrypt({plaintext, term()} | {encrypted, binary()}) -> term().
81+
-spec decrypt({plaintext, binary()} | {encrypted, binary()}) -> binary().
8282
decrypt(Term) ->
8383
gen_server:call(?MODULE, {decrypt, Term}, ?TIMEOUT).
8484

@@ -103,7 +103,7 @@ handle_call(refresh_config, _From, State0) ->
103103
{ok, State1} = refresh_config(State0),
104104
{reply, ok, State1};
105105
handle_call({encrypt, Term}, _From, #state{enabled=false}=State) ->
106-
{reply, Term, State};
106+
{reply, to_binary(Term), State};
107107
handle_call({encrypt, Term}, _From, #state{cipher=Cipher,
108108
hash=Hash,
109109
iterations=Iterations,
@@ -113,9 +113,9 @@ handle_call({encrypt, Term}, _From, #state{cipher=Cipher,
113113
% upon decryption.
114114
ClearText = {?VALUE_TAG, to_binary(Term)},
115115
Encrypted = credentials_obfuscation_pbe:encrypt_term(Cipher, Hash, Iterations, Secret, ClearText),
116-
case Encrypted of
117-
{plaintext, _} ->
118-
{reply, {plaintext, Term}, State};
116+
case Encrypted of
117+
{plaintext, {?VALUE_TAG, Bin}} ->
118+
{reply, {plaintext, Bin}, State};
119119
_ -> {reply, Encrypted, State}
120120
end;
121121
handle_call({decrypt, Term}, _From, #state{enabled=false}=State) ->

test/credentials_obfuscation_SUITE.erl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ encryption_happens_only_when_secret_available(_Config) ->
147147
?assertEqual({plaintext, Uri}, NotReallyEncryptedUri),
148148
?assertEqual(Uri, credentials_obfuscation:decrypt(NotReallyEncryptedUri)),
149149

150+
%% Strings are converted to binaries even if no secret available
151+
UriStr = "amqp://super:secret@localhost:5672",
152+
NotReallyEncryptedUri2 = credentials_obfuscation:encrypt(UriStr),
153+
?assertEqual({plaintext, Uri}, NotReallyEncryptedUri2),
154+
?assertEqual(Uri, credentials_obfuscation:decrypt(NotReallyEncryptedUri2)),
155+
150156
%% Start epmd
151157
os:cmd("epmd -daemon"),
152158

@@ -181,6 +187,11 @@ disabled(_Config) ->
181187
Credentials = <<"guest">>,
182188
?assertEqual(Credentials, credentials_obfuscation:encrypt(Credentials)),
183189
?assertEqual(Credentials, credentials_obfuscation:decrypt(Credentials)),
190+
191+
%% Strings are converted to binaries even if no secret available
192+
CredentialsStr = "guest",
193+
?assertEqual(Credentials, credentials_obfuscation:encrypt(CredentialsStr)),
194+
?assertEqual(Credentials, credentials_obfuscation:decrypt(Credentials)),
184195
ok.
185196

186197
refresh_configuration(_Config) ->

0 commit comments

Comments
 (0)