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_checksum_t * svn_checksum__from_digest(const unsigned char *digest, svn_checksum_kind_t kind, apr_pool_t *result_pool) { svn_checksum_t *checksum = svn_checksum_create(kind, result_pool); memcpy((unsigned char *)checksum->digest, digest, DIGESTSIZE(kind)); return checksum; }
svn_checksum_t * svn_checksum_create(svn_checksum_kind_t kind, apr_pool_t *pool) { svn_checksum_t *checksum; switch (kind) { case svn_checksum_md5: case svn_checksum_sha1: checksum = apr_pcalloc(pool, sizeof(*checksum) + DIGESTSIZE(kind)); checksum->digest = (unsigned char *)checksum + sizeof(*checksum); checksum->kind = kind; return checksum; default: return NULL; } }
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; }
apr_size_t svn_checksum_size(const svn_checksum_t *checksum) { return DIGESTSIZE(checksum->kind); }