/* --*- c -*-- * Copyright (C) 2008 Enrico Scholz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef H_UTIL_VSERVER_LIB_INTERNAL_CRYPTO_WRAPPER_NSS_H #define H_UTIL_VSERVER_LIB_INTERNAL_CRYPTO_WRAPPER_NSS_H #include #include #include #include "util-cast.h" typedef struct SECHashObjectStr ensc_hash_method; typedef struct HASHContextStr *ensc_hash_context; inline static int ensc_crypto_init(void) { NSS_NoDB_Init(NULL); return 0; } inline static ensc_hash_method const * ensc_crypto_hash_get_default(void) { return HASH_GetHashObject(SEC_OID_SHA1); } inline static ensc_hash_method const * ensc_crypto_hash_find(char const *id_c) { SECOidTag oid; #if 1 char *id = strdupa(id_c); char *ptr = id; while (*ptr) { *ptr = tolower(*ptr); ++ptr; } ptr = id; while ((ptr=strchr(ptr, '-'))!=NULL) memmove(ptr, ptr+1, strlen(ptr)); if (strcmp(id, "md2")==0) oid = SEC_OID_MD2; else if (strcmp(id, "md5")==0) oid = SEC_OID_MD5; else if (strcmp(id, "sha1")==0) oid = SEC_OID_SHA1; else if (strcasecmp(id, "sha256")==0) oid = SEC_OID_SHA256; else if (strcasecmp(id, "sha384")==0) oid = SEC_OID_SHA384; else if (strcasecmp(id, "sha512")==0) oid = SEC_OID_SHA512; else oid = SEC_OID_UNKNOWN; #else struct SECItemStr const item = { .type = ???, .data = const_cast(unsigned char *)(static_cast(unsigned char const *)(id)), .len = strlen(id) }; SECOidTag oid; oid = SECOID_FindOIDTag(&item); #endif return HASH_GetHashObjectByOidTag(oid); } inline static char const * ensc_crypto_hash_get_name(ensc_hash_method const *m) { char const * const NAMES[] = { [HASH_AlgNULL] = "null", [HASH_AlgMD2] = "md2", [HASH_AlgMD5] = "md5", [HASH_AlgSHA1] = "sha1", [HASH_AlgSHA256] = "sha256", [HASH_AlgSHA384] = "sha384", [HASH_AlgSHA512] = "sha512", }; size_t idx = static_cast(size_t)(m->type); if (idx >= sizeof(NAMES)/sizeof(NAMES[0])) return NULL; return NAMES[idx]; /* TODO: use SECOID_FindOIDTagDescription()? */ } inline static size_t ensc_crypto_hash_get_digestsize(ensc_hash_method const *m) { size_t const SIZES[] = { [HASH_AlgMD2] = MD2_LENGTH, [HASH_AlgMD5] = MD5_LENGTH, [HASH_AlgSHA1] = SHA1_LENGTH, [HASH_AlgSHA256] = SHA256_LENGTH, [HASH_AlgSHA384] = SHA384_LENGTH, [HASH_AlgSHA512] = SHA512_LENGTH, }; size_t idx = static_cast(size_t)(m->type); if (idx >= sizeof(SIZES)/sizeof(SIZES[0])) return 0; return SIZES[idx]; } inline static size_t ensc_crypto_hashctx_get_digestsize(ensc_hash_context const *ctx) { return ensc_crypto_hash_get_digestsize((*ctx)->hashobj); } inline static int ensc_crypto_hashctx_get_digest(ensc_hash_context *ctx, void *result, size_t UNUSED *res_len_a, size_t UNUSED max_res_len) { unsigned int res_len; HASH_End(*ctx, result, &res_len, max_res_len); if (res_len_a) *res_len_a = res_len; return 0; } inline static int ensc_crypto_hashctx_init(ensc_hash_context *ctx, ensc_hash_method const *m) { *ctx = HASH_Create(m->type); return *ctx==NULL ? -1 : 0; } inline static int ensc_crypto_hashctx_update(ensc_hash_context *ctx, void const *src, size_t len) { HASH_Update(*ctx, src, len); return 0; } inline static int ensc_crypto_hashctx_reset(ensc_hash_context *ctx) { HASH_Begin(*ctx); return 0; } inline static void ensc_crypto_hashctx_free(ensc_hash_context *ctx) { HASH_Destroy(*ctx); *ctx = NULL; } #endif /* H_UTIL_VSERVER_LIB_INTERNAL_CRYPTO_WRAPPER_NSS_H */