Tagging module util-vserver - util-vserver-0.30.215-6
[util-vserver.git] / lib_internal / crypto-wrapper-nss.h
1 /*      --*- c -*--
2  * Copyright (C) 2008 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 3 of the License.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16
17 #ifndef H_UTIL_VSERVER_LIB_INTERNAL_CRYPTO_WRAPPER_NSS_H
18 #define H_UTIL_VSERVER_LIB_INTERNAL_CRYPTO_WRAPPER_NSS_H
19
20 #include <sechash.h>
21 #include <secoid.h>
22 #include <nss.h>
23
24 #include "util-cast.h"
25
26 typedef struct SECHashObjectStr         ensc_hash_method;
27 typedef struct HASHContextStr           *ensc_hash_context;
28
29 inline static int
30 ensc_crypto_init(void)
31 {
32         NSS_NoDB_Init(NULL);
33         return 0;
34 }
35
36 inline static ensc_hash_method const *
37 ensc_crypto_hash_get_default(void)
38 {
39         return HASH_GetHashObject(SEC_OID_SHA1);
40 }
41
42 inline static ensc_hash_method const *
43 ensc_crypto_hash_find(char const *id_c)
44 {
45         SECOidTag               oid;
46
47 #if 1
48         char                    *id = strdupa(id_c);
49         char                    *ptr = id;
50
51         while (*ptr) {
52                 *ptr = tolower(*ptr);
53                 ++ptr;
54         }
55
56         ptr = id;
57         while ((ptr=strchr(ptr, '-'))!=NULL)
58                 memmove(ptr, ptr+1, strlen(ptr));
59         
60         if (strcmp(id, "md2")==0)
61                 oid = SEC_OID_MD2;
62         else if (strcmp(id, "md5")==0)
63                 oid = SEC_OID_MD5;
64         else if (strcmp(id, "sha1")==0)
65                 oid = SEC_OID_SHA1;
66         else if (strcasecmp(id, "sha256")==0)
67                 oid = SEC_OID_SHA256;
68         else if (strcasecmp(id, "sha384")==0)
69                 oid = SEC_OID_SHA384;
70         else if (strcasecmp(id, "sha512")==0)
71                 oid = SEC_OID_SHA512;
72         else
73                 oid = SEC_OID_UNKNOWN;
74                 
75 #else
76         struct SECItemStr const item = {
77                 .type = ???,
78                 .data = const_cast(unsigned char *)(static_cast(unsigned char const *)(id)),
79                 .len  = strlen(id)
80         };
81         SECOidTag               oid;
82         
83         oid = SECOID_FindOIDTag(&item);
84 #endif
85
86         return HASH_GetHashObjectByOidTag(oid);
87 }
88
89 inline static char const *
90 ensc_crypto_hash_get_name(ensc_hash_method const *m)
91 {
92         char const * const      NAMES[] = {
93                 [HASH_AlgNULL]   = "null",
94                 [HASH_AlgMD2]    = "md2",
95                 [HASH_AlgMD5]    = "md5",
96                 [HASH_AlgSHA1]   = "sha1",
97                 [HASH_AlgSHA256] = "sha256",
98                 [HASH_AlgSHA384] = "sha384",
99                 [HASH_AlgSHA512] = "sha512",
100         };
101         size_t          idx = static_cast(size_t)(m->type);
102         
103         if (idx >= sizeof(NAMES)/sizeof(NAMES[0]))
104                 return NULL;
105         
106         return NAMES[idx];
107         /* TODO: use SECOID_FindOIDTagDescription()? */
108 }
109
110 inline static size_t
111 ensc_crypto_hash_get_digestsize(ensc_hash_method const *m)
112 {
113         size_t const            SIZES[] = {
114                 [HASH_AlgMD2]    = MD2_LENGTH,
115                 [HASH_AlgMD5]    = MD5_LENGTH,
116                 [HASH_AlgSHA1]   = SHA1_LENGTH,
117                 [HASH_AlgSHA256] = SHA256_LENGTH,
118                 [HASH_AlgSHA384] = SHA384_LENGTH,
119                 [HASH_AlgSHA512] = SHA512_LENGTH,
120         };
121         size_t          idx = static_cast(size_t)(m->type);
122         
123         if (idx >= sizeof(SIZES)/sizeof(SIZES[0]))
124                 return 0;
125         
126         return SIZES[idx];
127 }
128
129 inline static size_t
130 ensc_crypto_hashctx_get_digestsize(ensc_hash_context const *ctx)
131 {
132         return ensc_crypto_hash_get_digestsize((*ctx)->hashobj);
133 }
134
135 inline static int
136 ensc_crypto_hashctx_get_digest(ensc_hash_context *ctx, void *result,
137                                size_t UNUSED *res_len_a, size_t UNUSED max_res_len)
138 {
139         unsigned int    res_len;
140         
141         HASH_End(*ctx, result, &res_len, max_res_len);
142         if (res_len_a)
143                 *res_len_a = res_len;
144
145         return 0;
146 }
147
148 inline static int
149 ensc_crypto_hashctx_init(ensc_hash_context *ctx, ensc_hash_method const *m)
150 {
151         *ctx = HASH_Create(m->type);
152         return *ctx==NULL ? -1 : 0;
153 }
154
155 inline static int
156 ensc_crypto_hashctx_update(ensc_hash_context *ctx, void const *src, size_t len)
157 {
158         HASH_Update(*ctx, src, len);
159         return 0;
160 }
161
162 inline static int
163 ensc_crypto_hashctx_reset(ensc_hash_context *ctx)
164 {
165         HASH_Begin(*ctx);
166         return 0;
167 }
168
169 inline static void
170 ensc_crypto_hashctx_free(ensc_hash_context *ctx)
171 {
172         HASH_Destroy(*ctx);
173         *ctx = NULL;
174 }
175
176 #endif  /* H_UTIL_VSERVER_LIB_INTERNAL_CRYPTO_WRAPPER_NSS_H */