util-vserver 0.30.215.
[util-vserver.git] / lib_internal / crypto-wrapper-nss.h
diff --git a/lib_internal/crypto-wrapper-nss.h b/lib_internal/crypto-wrapper-nss.h
new file mode 100644 (file)
index 0000000..ae0128d
--- /dev/null
@@ -0,0 +1,176 @@
+/*     --*- c -*--
+ * Copyright (C) 2008 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_UTIL_VSERVER_LIB_INTERNAL_CRYPTO_WRAPPER_NSS_H
+#define H_UTIL_VSERVER_LIB_INTERNAL_CRYPTO_WRAPPER_NSS_H
+
+#include <sechash.h>
+#include <secoid.h>
+#include <nss.h>
+
+#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 */