svn_error_t * svn_checksum(svn_checksum_t **checksum, svn_checksum_kind_t kind, const void *data, apr_size_t len, apr_pool_t *pool) { apr_sha1_ctx_t sha1_ctx; SVN_ERR(validate_kind(kind)); *checksum = svn_checksum_create(kind, pool); switch (kind) { case svn_checksum_md5: apr_md5((unsigned char *)(*checksum)->digest, data, len); break; case svn_checksum_sha1: apr_sha1_init(&sha1_ctx); apr_sha1_update(&sha1_ctx, data, len); apr_sha1_final((unsigned char *)(*checksum)->digest, &sha1_ctx); break; default: /* We really shouldn't get here, but if we do... */ return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL, NULL); } return SVN_NO_ERROR; }
svn_error_t * svn_checksum_clear(svn_checksum_t *checksum) { SVN_ERR(validate_kind(checksum->kind)); memset((unsigned char *) checksum->digest, 0, DIGESTSIZE(checksum->kind)); return SVN_NO_ERROR; }
svn_error_t * svn_checksum_parse_hex(svn_checksum_t **checksum, svn_checksum_kind_t kind, const char *hex, apr_pool_t *pool) { int i, len; char is_nonzero = '\0'; char *digest; static const char xdigitval[256] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1, /* 0-9 */ -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* A-F */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* a-f */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; if (hex == NULL) { *checksum = NULL; return SVN_NO_ERROR; } SVN_ERR(validate_kind(kind)); *checksum = svn_checksum_create(kind, pool); digest = (char *)(*checksum)->digest; len = DIGESTSIZE(kind); for (i = 0; i < len; i++) { char x1 = xdigitval[(unsigned char)hex[i * 2]]; char x2 = xdigitval[(unsigned char)hex[i * 2 + 1]]; if (x1 == (char)-1 || x2 == (char)-1) return svn_error_create(SVN_ERR_BAD_CHECKSUM_PARSE, NULL, NULL); digest[i] = (x1 << 4) | x2; is_nonzero |= (x1 << 4) | x2; } if (!is_nonzero) *checksum = NULL; return SVN_NO_ERROR; }
svn_error_t * svn_checksum_parse_hex(svn_checksum_t **checksum, svn_checksum_kind_t kind, const char *hex, apr_pool_t *pool) { int len; int i; unsigned char is_zeros = '\0'; if (hex == NULL) { *checksum = NULL; return SVN_NO_ERROR; } SVN_ERR(validate_kind(kind)); *checksum = svn_checksum_create(kind, pool); len = DIGESTSIZE(kind); for (i = 0; i < len; i++) { if ((! isxdigit(hex[i * 2])) || (! isxdigit(hex[i * 2 + 1]))) return svn_error_create(SVN_ERR_BAD_CHECKSUM_PARSE, NULL, NULL); ((unsigned char *)(*checksum)->digest)[i] = (( isalpha(hex[i*2]) ? hex[i*2] - 'a' + 10 : hex[i*2] - '0') << 4) | ( isalpha(hex[i*2+1]) ? hex[i*2+1] - 'a' + 10 : hex[i*2+1] - '0'); is_zeros |= (*checksum)->digest[i]; } if (is_zeros == '\0') *checksum = NULL; return SVN_NO_ERROR; }