Skip to content
This repository has been archived by the owner. It is now read-only.
Browse files
Use a constant time algorithm to compare signature strings.
This guards against timing attacks of the class outlined
  • Loading branch information
janl committed Oct 14, 2011
1 parent 29cb478 commit 8abf2d69fa5aa4c78c1a6222336d6e0dff7904b3
Showing 1 changed file with 18 additions and 2 deletions.
@@ -124,10 +124,10 @@ hmac_sha1_signature(BaseString, Consumer, TokenSecret) ->
base64:encode_to_string(crypto:sha_mac(Key, BaseString)).

hmac_sha1_verify(Signature, HttpMethod, URL, Params, Consumer, TokenSecret) ->
Signature =:= hmac_sha1_signature(HttpMethod, URL, Params, Consumer, TokenSecret).
verify_in_constant_time(Signature, hmac_sha1_signature(HttpMethod, URL, Params, Consumer, TokenSecret)).

hmac_sha1_verify(Signature, BaseString, Consumer, TokenSecret) ->
Signature =:= hmac_sha1_signature(BaseString, Consumer, TokenSecret).
verify_in_constant_time(Signature, hmac_sha1_signature(BaseString, Consumer, TokenSecret)).

rsa_sha1_signature(HttpMethod, URL, Params, Consumer) ->
BaseString = signature_base_string(HttpMethod, URL, Params),
@@ -145,6 +145,22 @@ rsa_sha1_verify(Signature, BaseString, Consumer) ->
Key = read_cert_key(consumer_secret(Consumer)),
public_key:verify(to_binary(BaseString), sha, base64:decode(Signature), Key).

verify_in_constant_time([X|RestX], [Y|RestY], Result) ->
verify_in_constant_time(RestX, RestY, (X bxor Y) bor Result);
verify_in_constant_time([], [], Result) ->
Result == 0.

verify_in_constant_time(<<X/binary>>, <<Y/binary>>) ->
verify_in_constant_time(binary_to_list(X), binary_to_list(Y));
verify_in_constant_time(X, Y) when is_list(X) and is_list(Y) ->
case length(X) == length(Y) of
true ->
verify_in_constant_time(X, Y, 0);
false ->
verify_in_constant_time(_X, _Y) -> false.

signature_base_string(HttpMethod, URL, Params) ->
uri_join([HttpMethod, uri_normalize(URL), params_encode(Params)]).

0 comments on commit 8abf2d6

Please sign in to comment.