-! Copyright (C) 2008, 2010 Slava Pestov
+! Copyright (C) 2008, 2010, 2016 Slava Pestov, Alexander Ilin
! See http://factorcode.org/license.txt for BSD license.
-USING: accessors byte-arrays alien.c-types alien.data kernel
-continuations destructors sequences io openssl openssl.libcrypto
-checksums checksums.stream classes.struct ;
+USING: accessors alien.c-types alien.data checksums
+checksums.stream destructors io kernel openssl openssl.libcrypto
+sequences ;
IN: checksums.openssl
ERROR: unknown-digest name ;
C: <openssl-checksum> openssl-checksum
-<PRIVATE
-
TUPLE: evp-md-context < disposable handle ;
: <evp-md-context> ( -- ctx )
M: evp-md-context dispose*
handle>> EVP_MD_CTX_destroy ;
-: with-evp-md-context ( quot -- )
- maybe-init-ssl [ <evp-md-context> ] dip with-disposal ; inline
+<PRIVATE
: digest-named ( name -- md )
dup EVP_get_digestbyname
: set-digest ( name ctx -- )
handle>> swap digest-named f EVP_DigestInit_ex ssl-error ;
-: checksum-loop ( ctx -- )
- dup handle>>
- 4096 read-partial dup [
- dup length EVP_DigestUpdate ssl-error
- checksum-loop
- ] [ 3drop ] if ;
+PRIVATE>
-: digest-value ( ctx -- value )
+M: openssl-checksum initialize-checksum-state ( checksum -- evp-md-context )
+ maybe-init-ssl name>> <evp-md-context> [ set-digest ] keep ;
+
+M: evp-md-context add-checksum-bytes ( ctx bytes -- ctx' )
+ [ dup handle>> ] dip dup length EVP_DigestUpdate ssl-error ;
+
+M: evp-md-context get-checksum ( ctx -- value )
handle>>
{ { int EVP_MAX_MD_SIZE } int }
[ EVP_DigestFinal_ex ssl-error ] with-out-parameters
memory>byte-array ;
-PRIVATE>
+M: openssl-checksum checksum-bytes ( bytes checksum -- value )
+ initialize-checksum-state [ swap add-checksum-bytes get-checksum ] with-disposal ;
-M: openssl-checksum checksum-stream
- name>> swap [
- [
- [ set-digest ]
- [ checksum-loop ]
- [ digest-value ]
- tri
- ] with-evp-md-context
- ] with-input-stream ;
+M: openssl-checksum checksum-stream ( stream checksum -- value )
+ initialize-checksum-state [ swap add-checksum-stream get-checksum ] with-disposal ;