From 395b55f0cf83c370a94c949eb3a0e9ad522cd3fc Mon Sep 17 00:00:00 2001 From: shove Date: Mon, 30 Oct 2023 15:30:34 +0800 Subject: [PATCH] crypto.md5: fix calculating the same hash values, when .sum() is called several times (#19703) --- vlib/crypto/md5/md5.v | 15 +++++++++++++-- vlib/crypto/md5/md5_test.v | 4 +++- vlib/crypto/sha1/sha1.v | 5 ++++- vlib/crypto/sha256/sha256.v | 5 ++++- vlib/crypto/sha512/sha512.v | 5 ++++- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/vlib/crypto/md5/md5.v b/vlib/crypto/md5/md5.v index fff3f0d514..aebe75d13e 100644 --- a/vlib/crypto/md5/md5.v +++ b/vlib/crypto/md5/md5.v @@ -58,6 +58,14 @@ pub fn (mut d Digest) reset() { d.len = 0 } +fn (d &Digest) clone() &Digest { + return &Digest{ + ...d + s: d.s.clone() + x: d.x.clone() + } +} + // new returns a new Digest (implementing hash.Hash) computing the MD5 checksum. pub fn new() &Digest { mut d := &Digest{} @@ -103,7 +111,7 @@ pub fn (mut d Digest) write(p_ []u8) !int { // sum returns the md5 sum of the bytes in `b_in`. pub fn (d &Digest) sum(b_in []u8) []u8 { // Make a copy of d so that caller can keep writing and summing. - mut d0 := *d + mut d0 := d.clone() hash := d0.checksum() mut b_out := b_in.clone() for b in hash { @@ -112,7 +120,10 @@ pub fn (d &Digest) sum(b_in []u8) []u8 { return b_out } -// checksum returns the byte checksum of the `Digest`. +// checksum returns the byte checksum of the `Digest`, +// it is an internal method and is not recommended because its results are not idempotent. +[deprecated: 'checksum() will be changed to a private method, use sum() instead'] +[deprecated_after: '2024-04-30'] pub fn (mut d Digest) checksum() []u8 { // Append 0x80 to the end of the message and then append zeros // until the length is a multiple of 56 bytes. Finally append diff --git a/vlib/crypto/md5/md5_test.v b/vlib/crypto/md5/md5_test.v index ddfaa6544f..1a3ba3e10a 100644 --- a/vlib/crypto/md5/md5_test.v +++ b/vlib/crypto/md5/md5_test.v @@ -11,7 +11,9 @@ fn test_crypto_md5_writer() { mut digest := md5.new() digest.write('this is a'.bytes()) or { assert false } digest.write(' md5 checksum.'.bytes()) or { assert false } - sum := digest.sum([]) + mut sum := digest.sum([]) + assert sum.hex() == '6fb421ff99036547655984da12973431' + sum = digest.sum([]) assert sum.hex() == '6fb421ff99036547655984da12973431' } diff --git a/vlib/crypto/sha1/sha1.v b/vlib/crypto/sha1/sha1.v index 061b077a82..2b20b1c304 100644 --- a/vlib/crypto/sha1/sha1.v +++ b/vlib/crypto/sha1/sha1.v @@ -127,7 +127,10 @@ pub fn (d &Digest) sum(b_in []u8) []u8 { return b_out } -// checksum returns the current byte checksum of the `Digest`. +// checksum returns the current byte checksum of the `Digest`, +// it is an internal method and is not recommended because its results are not idempotent. +[deprecated: 'checksum() will be changed to a private method, use sum() instead'] +[deprecated_after: '2024-04-30'] pub fn (mut d Digest) checksum() []u8 { mut len := d.len // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. diff --git a/vlib/crypto/sha256/sha256.v b/vlib/crypto/sha256/sha256.v index 82c19dd34e..f794569a85 100644 --- a/vlib/crypto/sha256/sha256.v +++ b/vlib/crypto/sha256/sha256.v @@ -167,7 +167,10 @@ pub fn (d &Digest) sum(b_in []u8) []u8 { return b_out } -// checksum returns the current byte checksum of the Digest. +// checksum returns the current byte checksum of the Digest, +// it is an internal method and is not recommended because its results are not idempotent. +[deprecated: 'checksum() will be changed to a private method, use sum() instead'] +[deprecated_after: '2024-04-30'] pub fn (mut d Digest) checksum() []u8 { mut len := d.len // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. diff --git a/vlib/crypto/sha512/sha512.v b/vlib/crypto/sha512/sha512.v index 208e738605..13d66b08ca 100644 --- a/vlib/crypto/sha512/sha512.v +++ b/vlib/crypto/sha512/sha512.v @@ -239,7 +239,10 @@ pub fn (d &Digest) sum(b_in []u8) []u8 { return b_out } -// checksum returns the current byte checksum of the Digest. +// checksum returns the current byte checksum of the Digest, +// it is an internal method and is not recommended because its results are not idempotent. +[deprecated: 'checksum() will be changed to a private method, use sum() instead'] +[deprecated_after: '2024-04-30'] pub fn (mut d Digest) checksum() []u8 { // Padding. Add a 1 bit and 0 bits until 112 bytes mod 128. mut len := d.len