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_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;
}
示例#4
0
static svn_error_t *
zero_match(apr_pool_t *pool)
{
  svn_checksum_t *zero_md5;
  svn_checksum_t *zero_sha1;
  svn_checksum_t *A_md5;
  svn_checksum_t *B_md5;
  svn_checksum_t *A_sha1;
  svn_checksum_t *B_sha1;


  zero_md5 = svn_checksum_create(svn_checksum_md5, pool);
  SVN_ERR(svn_checksum_clear(zero_md5));
  SVN_ERR(svn_checksum(&A_md5, svn_checksum_md5, "A", 1, pool));
  SVN_ERR(svn_checksum(&B_md5, svn_checksum_md5, "B", 1, pool));

  zero_sha1 = svn_checksum_create(svn_checksum_sha1, pool);
  SVN_ERR(svn_checksum_clear(zero_sha1));
  SVN_ERR(svn_checksum(&A_sha1, svn_checksum_sha1, "A", 1, pool));
  SVN_ERR(svn_checksum(&B_sha1, svn_checksum_sha1, "B", 1, pool));

  /* Different non-zero don't match. */
  SVN_TEST_ASSERT(!svn_checksum_match(A_md5, B_md5));
  SVN_TEST_ASSERT(!svn_checksum_match(A_sha1, B_sha1));
  SVN_TEST_ASSERT(!svn_checksum_match(A_md5, A_sha1));
  SVN_TEST_ASSERT(!svn_checksum_match(A_md5, B_sha1));

  /* Zero matches anything of the same kind. */
  SVN_TEST_ASSERT(svn_checksum_match(A_md5, zero_md5));
  SVN_TEST_ASSERT(svn_checksum_match(zero_md5, B_md5));
  SVN_TEST_ASSERT(svn_checksum_match(A_sha1, zero_sha1));
  SVN_TEST_ASSERT(svn_checksum_match(zero_sha1, B_sha1));

  /* Zero doesn't match anything of a different kind... */
  SVN_TEST_ASSERT(!svn_checksum_match(zero_md5, A_sha1));
  SVN_TEST_ASSERT(!svn_checksum_match(zero_sha1, A_md5));
  /* ...even another zero. */
  SVN_TEST_ASSERT(!svn_checksum_match(zero_md5, zero_sha1));

  return SVN_NO_ERROR;
}
示例#5
0
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;
}
svn_error_t *
svn_checksum_final(svn_checksum_t **checksum,
                   const svn_checksum_ctx_t *ctx,
                   apr_pool_t *pool)
{
  *checksum = svn_checksum_create(ctx->kind, pool);

  switch (ctx->kind)
    {
      case svn_checksum_md5:
        apr_md5_final((unsigned char *)(*checksum)->digest, ctx->apr_ctx);
        break;

      case svn_checksum_sha1:
        apr_sha1_final((unsigned char *)(*checksum)->digest, ctx->apr_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;
}