From d7d047f439880735377a4b8ea2ce2ef42921fff8 Mon Sep 17 00:00:00 2001 From: Adam Kocoloski Date: Tue, 4 May 2010 20:46:42 +0000 Subject: use crypto:md5 when available. thx fdmanana. Closes COUCHDB-757 git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@941033 13f79535-47bb-0310-9956-ffa450edef68 --- src/couchdb/couch_db.erl | 2 +- src/couchdb/couch_file.erl | 14 +++++++------- src/couchdb/couch_httpd.erl | 2 +- src/couchdb/couch_native_process.erl | 4 ++-- src/couchdb/couch_rep.erl | 2 +- src/couchdb/couch_stream.erl | 28 ++++++++++++++-------------- src/couchdb/couch_util.erl | 17 +++++++++++++++++ src/couchdb/couch_view_group.erl | 2 +- test/etap/130-attachments-md5.t | 6 +++--- 9 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/couchdb/couch_db.erl b/src/couchdb/couch_db.erl index 993dab76..89530e73 100644 --- a/src/couchdb/couch_db.erl +++ b/src/couchdb/couch_db.erl @@ -564,7 +564,7 @@ new_revid(#doc{body=Body,revs={OldStart,OldRevs}, ?l2b(integer_to_list(couch_util:rand32())); Atts2 -> OldRev = case OldRevs of [] -> 0; [OldRev0|_] -> OldRev0 end, - erlang:md5(term_to_binary([Deleted, OldStart, OldRev, Body, Atts2])) + couch_util:md5(term_to_binary([Deleted, OldStart, OldRev, Body, Atts2])) end. new_revs([], OutBuckets, IdRevsAcc) -> diff --git a/src/couchdb/couch_file.erl b/src/couchdb/couch_file.erl index 4c6928a7..64a9ed7b 100644 --- a/src/couchdb/couch_file.erl +++ b/src/couchdb/couch_file.erl @@ -89,7 +89,7 @@ append_binary(Fd, Bin) -> append_binary_md5(Fd, Bin) -> Size = iolist_size(Bin), gen_server:call(Fd, {append_bin, - [<<1:1/integer,Size:31/integer>>, erlang:md5(Bin), Bin]}, infinity). + [<<1:1/integer,Size:31/integer>>, couch_util:md5(Bin), Bin]}, infinity). %%---------------------------------------------------------------------- @@ -124,7 +124,7 @@ pread_iolist(Fd, Pos) -> {ok, Md5List, ValPos} = read_raw_iolist(Fd, NextPos, 16), Md5 = iolist_to_binary(Md5List), {ok, IoList, _} = read_raw_iolist(Fd,ValPos,Len), - case erlang:md5(IoList) of + case couch_util:md5(IoList) of Md5 -> ok; _ -> throw(file_corruption) end, @@ -212,7 +212,7 @@ read_header(Fd) -> write_header(Fd, Data) -> Bin = term_to_binary(Data), - Md5 = erlang:md5(Bin), + Md5 = couch_util:md5(Bin), % now we assemble the final header binary and write to disk FinalBin = <>, gen_server:call(Fd, {write_header, FinalBin}, infinity). @@ -314,7 +314,7 @@ handle_call({upgrade_old_header, Prefix}, _From, #file{fd=Fd}=File) -> {ok, Header} -> {ok, TailAppendBegin} = file:position(Fd, eof), Bin = term_to_binary(Header), - Md5 = erlang:md5(Bin), + Md5 = couch_util:md5(Bin), % now we assemble the final header binary and write to disk FinalBin = <>, {reply, ok, _} = handle_call({write_header, FinalBin}, ok, File), @@ -395,7 +395,7 @@ extract_header(Prefix, Bin) -> case HeaderPrefix of Prefix -> % check the integrity signature - case erlang:md5(TermBin) == Sig of + case couch_util:md5(TermBin) == Sig of true -> Header = binary_to_term(TermBin), {ok, Header}; @@ -425,7 +425,7 @@ write_old_header(Fd, Prefix, Data) -> ok = file:sync(Fd), % pad out the header with zeros, then take the md5 hash PadZeros = <<0:(8*(?HEADER_SIZE - FilledSize2))>>, - Sig = erlang:md5([TermBin2, PadZeros]), + Sig = couch_util:md5([TermBin2, PadZeros]), % now we assemble the final header binary and write to disk WriteBin = <>, ?HEADER_SIZE = size(WriteBin), % sanity check @@ -465,7 +465,7 @@ load_header(Fd, Block) -> file:pread(Fd, (Block*?SIZE_BLOCK) + 5, TotalBytes), <> = iolist_to_binary(remove_block_prefixes(1, RawBin)), - Md5Sig = erlang:md5(HeaderBin), + Md5Sig = couch_util:md5(HeaderBin), {ok, HeaderBin}. calculate_total_read_len(0, FinalLen) -> diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl index db9fee49..f0217a4e 100644 --- a/src/couchdb/couch_httpd.erl +++ b/src/couchdb/couch_httpd.erl @@ -426,7 +426,7 @@ doc_etag(#doc{revs={Start, [DiskRev|_]}}) -> "\"" ++ ?b2l(couch_doc:rev_to_str({Start, DiskRev})) ++ "\"". make_etag(Term) -> - <> = erlang:md5(term_to_binary(Term)), + <> = couch_util:md5(term_to_binary(Term)), list_to_binary("\"" ++ lists:flatten(io_lib:format("~.36B",[SigInt])) ++ "\""). etag_match(Req, CurrentEtag) when is_binary(CurrentEtag) -> diff --git a/src/couchdb/couch_native_process.erl b/src/couchdb/couch_native_process.erl index e68db479..5a33dc82 100644 --- a/src/couchdb/couch_native_process.erl +++ b/src/couchdb/couch_native_process.erl @@ -313,11 +313,11 @@ bindings(State, Sig, DDoc) -> % thanks to erlview, via: % http://erlang.org/pipermail/erlang-questions/2003-November/010544.html makefun(State, Source) -> - Sig = erlang:md5(Source), + Sig = couch_util:md5(Source), BindFuns = bindings(State, Sig), {Sig, makefun(State, Source, BindFuns)}. makefun(State, Source, {DDoc}) -> - Sig = erlang:md5(lists:flatten([Source, term_to_binary(DDoc)])), + Sig = couch_util:md5(lists:flatten([Source, term_to_binary(DDoc)])), BindFuns = bindings(State, Sig, {DDoc}), {Sig, makefun(State, Source, BindFuns)}; makefun(_State, Source, BindFuns) when is_list(BindFuns) -> diff --git a/src/couchdb/couch_rep.erl b/src/couchdb/couch_rep.erl index eb62ad7c..3daf8170 100644 --- a/src/couchdb/couch_rep.erl +++ b/src/couchdb/couch_rep.erl @@ -465,7 +465,7 @@ make_replication_id({Props}, UserCtx) -> end, Extension = maybe_append_options( [<<"continuous">>, <<"create_target">>], Props), - {couch_util:to_hex(erlang:md5(term_to_binary(Base))), Extension}. + {couch_util:to_hex(couch_util:md5(term_to_binary(Base))), Extension}. maybe_add_trailing_slash(Url) -> re:replace(Url, "[^/]$", "&/", [{return, list}]). diff --git a/src/couchdb/couch_stream.erl b/src/couchdb/couch_stream.erl index b25cb2fc..04c17770 100644 --- a/src/couchdb/couch_stream.erl +++ b/src/couchdb/couch_stream.erl @@ -94,7 +94,7 @@ foldl(Fd, [Pos|Rest], Fun, Acc) -> foldl(Fd, PosList, <<>>, Fun, Acc) -> foldl(Fd, PosList, Fun, Acc); foldl(Fd, PosList, Md5, Fun, Acc) -> - foldl(Fd, PosList, Md5, erlang:md5_init(), Fun, Acc). + foldl(Fd, PosList, Md5, couch_util:md5_init(), Fun, Acc). foldl_decode(Fd, PosList, Md5, Enc, Fun, Acc) -> {DecDataFun, DecEndFun} = case Enc of @@ -104,34 +104,34 @@ foldl_decode(Fd, PosList, Md5, Enc, Fun, Acc) -> identity_enc_dec_funs() end, Result = foldl_decode( - DecDataFun, Fd, PosList, Md5, erlang:md5_init(), Fun, Acc + DecDataFun, Fd, PosList, Md5, couch_util:md5_init(), Fun, Acc ), DecEndFun(), Result. foldl(_Fd, [], Md5, Md5Acc, _Fun, Acc) -> - Md5 = erlang:md5_final(Md5Acc), + Md5 = couch_util:md5_final(Md5Acc), Acc; foldl(Fd, [Pos], Md5, Md5Acc, Fun, Acc) -> {ok, Bin} = couch_file:pread_iolist(Fd, Pos), - Md5 = erlang:md5_final(erlang:md5_update(Md5Acc, Bin)), + Md5 = couch_util:md5_final(couch_util:md5_update(Md5Acc, Bin)), Fun(Bin, Acc); foldl(Fd, [Pos|Rest], Md5, Md5Acc, Fun, Acc) -> {ok, Bin} = couch_file:pread_iolist(Fd, Pos), - foldl(Fd, Rest, Md5, erlang:md5_update(Md5Acc, Bin), Fun, Fun(Bin, Acc)). + foldl(Fd, Rest, Md5, couch_util:md5_update(Md5Acc, Bin), Fun, Fun(Bin, Acc)). foldl_decode(_DecFun, _Fd, [], Md5, Md5Acc, _Fun, Acc) -> - Md5 = erlang:md5_final(Md5Acc), + Md5 = couch_util:md5_final(Md5Acc), Acc; foldl_decode(DecFun, Fd, [Pos], Md5, Md5Acc, Fun, Acc) -> {ok, EncBin} = couch_file:pread_iolist(Fd, Pos), - Md5 = erlang:md5_final(erlang:md5_update(Md5Acc, EncBin)), + Md5 = couch_util:md5_final(couch_util:md5_update(Md5Acc, EncBin)), Bin = DecFun(EncBin), Fun(Bin, Acc); foldl_decode(DecFun, Fd, [Pos|Rest], Md5, Md5Acc, Fun, Acc) -> {ok, EncBin} = couch_file:pread_iolist(Fd, Pos), Bin = DecFun(EncBin), - Md5Acc2 = erlang:md5_update(Md5Acc, EncBin), + Md5Acc2 = couch_util:md5_update(Md5Acc, EncBin), foldl_decode(DecFun, Fd, Rest, Md5, Md5Acc2, Fun, Fun(Bin, Acc)). gzip_init(Options) -> @@ -190,8 +190,8 @@ init({Fd, Encoding, Options}) -> end, {ok, #stream{ fd=Fd, - md5=erlang:md5_init(), - identity_md5=erlang:md5_init(), + md5=couch_util:md5_init(), + identity_md5=couch_util:md5_init(), encoding_fun=EncodingFun, end_encoding_fun=EndEncodingFun } @@ -215,7 +215,7 @@ handle_call({write, Bin}, _From, Stream) -> encoding_fun = EncodingFun} = Stream, if BinSize + BufferLen > Max -> WriteBin = lists:reverse(Buffer, [Bin]), - IdenMd5_2 = erlang:md5_update(IdenMd5, WriteBin), + IdenMd5_2 = couch_util:md5_update(IdenMd5, WriteBin), case EncodingFun(WriteBin) of [] -> % case where the encoder did some internal buffering @@ -226,7 +226,7 @@ handle_call({write, Bin}, _From, Stream) -> WriteBin2 -> {ok, Pos} = couch_file:append_binary(Fd, WriteBin2), WrittenLen2 = WrittenLen + iolist_size(WriteBin2), - Md5_2 = erlang:md5_update(Md5, WriteBin2), + Md5_2 = couch_util:md5_update(Md5, WriteBin2), Written2 = [Pos|Written] end, @@ -257,9 +257,9 @@ handle_call(close, _From, Stream) -> end_encoding_fun = EndEncodingFun} = Stream, WriteBin = lists:reverse(Buffer), - IdenMd5Final = erlang:md5_final(erlang:md5_update(IdenMd5, WriteBin)), + IdenMd5Final = couch_util:md5_final(couch_util:md5_update(IdenMd5, WriteBin)), WriteBin2 = EncodingFun(WriteBin) ++ EndEncodingFun(), - Md5Final = erlang:md5_final(erlang:md5_update(Md5, WriteBin2)), + Md5Final = couch_util:md5_final(couch_util:md5_update(Md5, WriteBin2)), Result = case WriteBin2 of [] -> {lists:reverse(Written), WrittenLen, IdenLen, Md5Final, IdenMd5Final}; diff --git a/src/couchdb/couch_util.erl b/src/couchdb/couch_util.erl index e685332d..af27636b 100644 --- a/src/couchdb/couch_util.erl +++ b/src/couchdb/couch_util.erl @@ -24,6 +24,7 @@ -export([verify/2,simple_call/2,shutdown_sync/1]). -export([compressible_att_type/1]). -export([get_value/2, get_value/3]). +-export([md5/1, md5_init/0, md5_update/2, md5_final/1]). -include("couch_db.hrl"). -include_lib("kernel/include/file.hrl"). @@ -412,3 +413,19 @@ compressible_att_type(MimeType) -> end, [T || T <- TypeExpList, T /= []] ). + +-spec md5(Data::iodata()) -> Digest::binary(). +md5(Data) -> + try crypto:md5(Data) catch error:_ -> erlang:md5(Data) end. + +-spec md5_init() -> Context::binary(). +md5_init() -> + try crypto:md5_init() catch error:_ -> erlang:md5_init() end. + +-spec md5_update(Context::binary(), Data::iodata()) -> NewContext::binary(). +md5_update(Ctx, D) -> + try crypto:md5_update(Ctx,D) catch error:_ -> erlang:md5_update(Ctx,D) end. + +-spec md5_final(Context::binary()) -> Digest::binary(). +md5_final(Ctx) -> + try crypto:md5_final(Ctx) catch error:_ -> erlang:md5_final(Ctx) end. diff --git a/src/couchdb/couch_view_group.erl b/src/couchdb/couch_view_group.erl index 5acc7bb8..275d18d5 100644 --- a/src/couchdb/couch_view_group.erl +++ b/src/couchdb/couch_view_group.erl @@ -456,7 +456,7 @@ set_view_sig(#group{ views=Views, def_lang=Language, design_options=DesignOptions}=G) -> - G#group{sig=erlang:md5(term_to_binary({Views, Language, DesignOptions}))}. + G#group{sig=couch_util:md5(term_to_binary({Views, Language, DesignOptions}))}. open_db_group(DbName, GroupId) -> case couch_db:open_int(DbName, []) of diff --git a/test/etap/130-attachments-md5.t b/test/etap/130-attachments-md5.t index 5521632a..4c40f83a 100755 --- a/test/etap/130-attachments-md5.t +++ b/test/etap/130-attachments-md5.t @@ -103,7 +103,7 @@ test_identity_with_valid_md5() -> "PUT /", test_db_name(), "/", docid(), "/readme.txt HTTP/1.1\r\n", "Content-Type: text/plain\r\n", "Content-Length: 34\r\n", - "Content-MD5: ", base64:encode(erlang:md5(AttData)), "\r\n", + "Content-MD5: ", base64:encode(couch_util:md5(AttData)), "\r\n", "\r\n", AttData], @@ -118,7 +118,7 @@ test_chunked_with_valid_md5_header() -> "PUT /", test_db_name(), "/", docid(), "/readme.txt HTTP/1.1\r\n", "Content-Type: text/plain\r\n", "Transfer-Encoding: chunked\r\n", - "Content-MD5: ", base64:encode(erlang:md5(AttData)), "\r\n", + "Content-MD5: ", base64:encode(couch_util:md5(AttData)), "\r\n", "\r\n", to_hex(size(Part1)), "\r\n", Part1, "\r\n", @@ -145,7 +145,7 @@ test_chunked_with_valid_md5_trailer() -> to_hex(size(Part2)), "\r\n", Part2, "\r\n", "0\r\n", - "Content-MD5: ", base64:encode(erlang:md5(AttData)), "\r\n", + "Content-MD5: ", base64:encode(couch_util:md5(AttData)), "\r\n", "\r\n"], {Code, Json} = do_request(Data), -- cgit v1.2.3