Lines 19-28
Link Here
|
19 |
**************************************************************************** */ |
19 |
**************************************************************************** */ |
20 |
#ifdef WIN32 |
20 |
#ifdef WIN32 |
21 |
#include <win32.h> |
21 |
#include <win32.h> |
|
|
22 |
#pragma pack(push, cryptoki, 1) |
23 |
#include "pkcs11.h" |
24 |
#pragma pack(pop, cryptoki) |
22 |
#else |
25 |
#else |
23 |
#include <unix.h> |
26 |
#include <unix.h> |
24 |
#endif |
|
|
25 |
#include <pkcs11.h> |
27 |
#include <pkcs11.h> |
|
|
28 |
#endif |
26 |
#include <stdio.h> |
29 |
#include <stdio.h> |
27 |
#include <string.h> |
30 |
#include <string.h> |
28 |
#include <stdlib.h> |
31 |
#include <stdlib.h> |
Lines 33-98
Link Here
|
33 |
#include <config.h> |
36 |
#include <config.h> |
34 |
#endif |
37 |
#endif |
35 |
|
38 |
|
|
|
39 |
#include <stdbool.h> |
40 |
|
36 |
#if HAVE_OPENSSL |
41 |
#if HAVE_OPENSSL |
37 |
#include <openssl/rsa.h> |
42 |
#include <openssl/opensslv.h> |
|
|
43 |
#include <openssl/evp.h> |
38 |
#include <openssl/engine.h> |
44 |
#include <openssl/engine.h> |
39 |
|
45 |
|
40 |
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) |
46 |
// These were copied from eid-test-ca:derencode.c |
41 |
static int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { |
47 |
int verify_sig(const unsigned char *sig_in, CK_ULONG siglen, const unsigned char *certificate, size_t certlen, bool is_rsa) { |
42 |
if(!r || !n || !e) { |
48 |
#if OPENSSL_VERSION_NUMBER > 0x10100000L |
43 |
return 0; |
49 |
X509 *cert = NULL; |
44 |
} |
50 |
EVP_PKEY *pkey = NULL; |
45 |
r->n = n; |
51 |
EVP_MD_CTX *mdctx; |
46 |
r->e = e; |
52 |
EVP_PKEY_CTX *pctx; |
47 |
r->d = d; |
53 |
const EVP_MD *md = EVP_get_digestbyname("sha256"); |
48 |
return 1; |
54 |
unsigned char *sig = (unsigned char*)sig_in; |
49 |
} |
55 |
|
50 |
#endif |
56 |
if(d2i_X509(&cert, &certificate, certlen) == NULL) { |
51 |
|
57 |
fprintf(stderr, "E: could not parse X509 certificate\n"); |
52 |
CK_BYTE digest_sha256[] = { |
58 |
return TEST_RV_FAIL; |
53 |
0x2c, 0x26, 0xb4, 0x6b, |
59 |
} |
54 |
0x68, 0xff, 0xc6, 0x8f, |
60 |
pkey = X509_get0_pubkey(cert); |
55 |
0xf9, 0x9b, 0x45, 0x3c, |
61 |
if(pkey == NULL) { |
56 |
0x1d, 0x30, 0x41, 0x34, |
62 |
fprintf(stderr, "E: could not find public key in certificate\n"); |
57 |
0x13, 0x42, 0x2d, 0x70, |
63 |
return TEST_RV_FAIL; |
58 |
0x64, 0x83, 0xbf, 0xa0, |
64 |
} |
59 |
0xf9, 0x8a, 0x5e, 0x88, |
65 |
mdctx = EVP_MD_CTX_new(); |
60 |
0x62, 0x66, 0xe7, 0xae |
66 |
if(EVP_DigestVerifyInit(mdctx, &pctx, md, NULL, pkey) != 1) { |
61 |
}; |
67 |
fprintf(stderr, "E: initialization for signature validation failed!\n"); |
62 |
|
68 |
return TEST_RV_FAIL; |
63 |
int verify_sig(unsigned char* sig, CK_ULONG siglen, CK_BYTE_PTR modulus, CK_ULONG modlen, CK_BYTE_PTR exponent, CK_ULONG explen) { |
69 |
} |
64 |
RSA* rsa = RSA_new(); |
70 |
if(EVP_DigestVerifyUpdate(mdctx, (const unsigned char*)"foo", 3) != 1) { |
65 |
unsigned char* s = malloc(siglen); |
71 |
fprintf(stderr, "E: hashing for signature failed!\n"); |
66 |
int ret; |
72 |
return TEST_RV_FAIL; |
67 |
|
|
|
68 |
RSA_set0_key(rsa, BN_bin2bn(modulus, (int) modlen, NULL), BN_bin2bn(exponent, (int) explen, NULL), NULL); |
69 |
|
70 |
int v = RSA_verify(NID_sha256, digest_sha256, sizeof(digest_sha256), sig, siglen, rsa); |
71 |
|
72 |
printf("Signature verification returned: %d\n", v); |
73 |
if(!v) { |
74 |
unsigned long e = ERR_get_error(); |
75 |
printf("error %ld: %s\n", e, ERR_error_string(e, NULL)); |
76 |
ret = TEST_RV_FAIL; |
77 |
} else { |
78 |
ret = TEST_RV_OK; |
79 |
} |
73 |
} |
80 |
|
74 |
|
81 |
free(s); |
75 |
ECDSA_SIG* ec_sig; |
82 |
RSA_free(rsa); |
76 |
if(!is_rsa) { |
83 |
|
77 |
BIGNUM *r; |
84 |
return ret; |
78 |
BIGNUM *s; |
|
|
79 |
ec_sig = ECDSA_SIG_new(); |
80 |
if((r = BN_bin2bn(sig, siglen / 2, NULL)) == NULL) { |
81 |
fprintf(stderr, "E: could not convert R part of ECDSA signature!\n"); |
82 |
return TEST_RV_FAIL; |
83 |
} |
84 |
if((s = BN_bin2bn(sig + (siglen / 2), siglen / 2, NULL)) == NULL) { |
85 |
fprintf(stderr, "E: could not convert S part of ECDSA signature!\n"); |
86 |
return TEST_RV_FAIL; |
87 |
} |
88 |
if(ECDSA_SIG_set0(ec_sig, r, s) == 0) { |
89 |
fprintf(stderr, "E: could not set ECDSA_SIG structure!\n"); |
90 |
return TEST_RV_FAIL; |
91 |
} |
92 |
siglen = i2d_ECDSA_SIG(ec_sig, NULL); |
93 |
unsigned char *dersig = sig = malloc(siglen); |
94 |
siglen = i2d_ECDSA_SIG(ec_sig, &dersig); |
95 |
} |
96 |
if(EVP_DigestVerifyFinal(mdctx, sig, siglen) != 1) { |
97 |
fprintf(stderr, "E: signature fails validation!\n"); |
98 |
return TEST_RV_FAIL; |
99 |
} |
100 |
if(!is_rsa) { |
101 |
free(sig); |
102 |
} |
103 |
printf("signature verified\n"); |
104 |
return TEST_RV_OK; |
105 |
#else |
106 |
printf("OpenSSL too old for verification\n"); |
107 |
#endif |
85 |
} |
108 |
} |
86 |
|
|
|
87 |
#endif |
109 |
#endif |
88 |
|
110 |
|
89 |
int test_key(char* label, CK_SESSION_HANDLE session, CK_SLOT_ID slot) { |
111 |
int test_key(char* label, CK_SESSION_HANDLE session, CK_SLOT_ID slot) { |
90 |
CK_ATTRIBUTE attr[2]; |
112 |
CK_ATTRIBUTE attr[2]; |
91 |
CK_MECHANISM mech; |
113 |
CK_MECHANISM mech; |
|
|
114 |
CK_MECHANISM_TYPE_PTR mechlist; |
92 |
CK_BYTE data[] = { 'f', 'o', 'o' }; |
115 |
CK_BYTE data[] = { 'f', 'o', 'o' }; |
93 |
CK_BYTE_PTR sig, mod, exp; |
116 |
CK_BYTE_PTR sig, mod, exp; |
94 |
CK_ULONG sig_len, type, count; |
117 |
CK_ULONG sig_len, type, count; |
95 |
CK_OBJECT_HANDLE privatekey, publickey; |
118 |
CK_OBJECT_HANDLE privatekey, publickey, certificate; |
|
|
119 |
bool is_rsa = false; |
120 |
int i; |
96 |
|
121 |
|
97 |
attr[0].type = CKA_CLASS; |
122 |
attr[0].type = CKA_CLASS; |
98 |
attr[0].pValue = &type; |
123 |
attr[0].pValue = &type; |
Lines 113-119
Link Here
|
113 |
return TEST_RV_SKIP; |
138 |
return TEST_RV_SKIP; |
114 |
} |
139 |
} |
115 |
|
140 |
|
116 |
mech.mechanism = CKM_SHA256_RSA_PKCS; |
141 |
check_rv(C_GetMechanismList(slot, NULL_PTR, &count)); |
|
|
142 |
mechlist = malloc(sizeof(CK_MECHANISM_TYPE) * count); |
143 |
#undef CHECK_RV_DEALLOCATE |
144 |
#define CHECK_RV_DEALLOCATE free(mechlist) |
145 |
|
146 |
check_rv(C_GetMechanismList(slot, mechlist, &count)); |
147 |
|
148 |
for(i=0; i<count; i++) { |
149 |
if(mechlist[i] == CKM_SHA256_RSA_PKCS) { |
150 |
mech.mechanism = mechlist[i]; |
151 |
i=count; |
152 |
is_rsa = true; |
153 |
break; |
154 |
} |
155 |
} |
156 |
|
117 |
check_rv(C_SignInit(session, &mech, privatekey)); |
157 |
check_rv(C_SignInit(session, &mech, privatekey)); |
118 |
|
158 |
|
119 |
check_rv(C_Sign(session, data, sizeof(data), NULL, &sig_len)); |
159 |
check_rv(C_Sign(session, data, sizeof(data), NULL, &sig_len)); |
Lines 124-165
Link Here
|
124 |
|
164 |
|
125 |
hex_dump((char*)sig, sig_len); |
165 |
hex_dump((char*)sig, sig_len); |
126 |
|
166 |
|
127 |
type = CKO_PUBLIC_KEY; |
167 |
if(is_rsa) { |
128 |
check_rv(C_FindObjectsInit(session, attr, 2)); |
168 |
type = CKO_PUBLIC_KEY; |
129 |
check_rv(C_FindObjects(session, &publickey, 1, &count)); |
169 |
check_rv(C_FindObjectsInit(session, attr, 2)); |
130 |
verbose_assert(count == 1); |
170 |
check_rv(C_FindObjects(session, &publickey, 1, &count)); |
131 |
check_rv(C_FindObjectsFinal(session)); |
171 |
verbose_assert(count == 1); |
|
|
172 |
check_rv(C_FindObjectsFinal(session)); |
132 |
|
173 |
|
133 |
attr[0].type = CKA_MODULUS; |
174 |
attr[0].type = CKA_MODULUS; |
134 |
attr[0].pValue = NULL_PTR; |
175 |
attr[0].pValue = NULL_PTR; |
135 |
attr[0].ulValueLen = 0; |
176 |
attr[0].ulValueLen = 0; |
136 |
|
177 |
|
137 |
attr[1].type = CKA_PUBLIC_EXPONENT; |
178 |
attr[1].type = CKA_PUBLIC_EXPONENT; |
138 |
attr[1].pValue = NULL_PTR; |
179 |
attr[1].pValue = NULL_PTR; |
139 |
attr[1].ulValueLen = 0; |
180 |
attr[1].ulValueLen = 0; |
140 |
|
181 |
|
141 |
check_rv(C_GetAttributeValue(session, publickey, attr, 2)); |
182 |
check_rv(C_GetAttributeValue(session, publickey, attr, 2)); |
142 |
|
183 |
|
143 |
verbose_assert(attr[0].ulValueLen == sig_len); |
184 |
verbose_assert(attr[0].ulValueLen == sig_len); |
144 |
|
185 |
|
145 |
mod = malloc(attr[0].ulValueLen); |
186 |
mod = malloc(attr[0].ulValueLen); |
146 |
mod[0] = 0xde; mod[1] = 0xad; mod[2] = 0xbe; mod[3] = 0xef; |
187 |
mod[0] = 0xde; mod[1] = 0xad; mod[2] = 0xbe; mod[3] = 0xef; |
147 |
exp = malloc(attr[1].ulValueLen); |
188 |
exp = malloc(attr[1].ulValueLen); |
148 |
exp[0] = 0xde; exp[1] = 0xad; exp[2] = 0xbe; exp[3] = 0xef; |
189 |
exp[0] = 0xde; exp[1] = 0xad; exp[2] = 0xbe; exp[3] = 0xef; |
149 |
|
190 |
|
150 |
attr[0].pValue = mod; |
191 |
attr[0].pValue = mod; |
151 |
attr[1].pValue = exp; |
192 |
attr[1].pValue = exp; |
152 |
|
193 |
|
153 |
check_rv(C_GetAttributeValue(session, publickey, attr, 2)); |
194 |
check_rv(C_GetAttributeValue(session, publickey, attr, 2)); |
154 |
|
195 |
|
155 |
printf("Received key modulus with length %lu:\n", attr[0].ulValueLen); |
196 |
printf("Received key modulus with length %lu:\n", attr[0].ulValueLen); |
156 |
hex_dump((char*)mod, attr[0].ulValueLen); |
197 |
hex_dump((char*)mod, attr[0].ulValueLen); |
157 |
|
198 |
|
158 |
printf("Received public exponent of key with length %lu:\n", attr[1].ulValueLen); |
199 |
printf("Received public exponent of key with length %lu:\n", attr[1].ulValueLen); |
159 |
hex_dump((char*)exp, attr[1].ulValueLen); |
200 |
hex_dump((char*)exp, attr[1].ulValueLen); |
|
|
201 |
} |
160 |
|
202 |
|
161 |
#if HAVE_OPENSSL |
203 |
#if HAVE_OPENSSL && OPENSSL_VERSION_NUMBER > 0x10100000L |
162 |
return verify_sig(sig, sig_len, mod, attr[0].ulValueLen, exp, attr[1].ulValueLen); |
204 |
unsigned char cert[4096]; |
|
|
205 |
attr[0].type = CKA_CLASS; |
206 |
attr[0].pValue = &type; |
207 |
type = CKO_CERTIFICATE; |
208 |
attr[0].ulValueLen = sizeof(CK_ULONG); |
209 |
|
210 |
attr[1].type = CKA_LABEL; |
211 |
attr[1].pValue = label; |
212 |
attr[1].ulValueLen = strlen(label); |
213 |
|
214 |
check_rv(C_FindObjectsInit(session, attr, 2)); |
215 |
check_rv(C_FindObjects(session, &certificate, 1, &count)); |
216 |
verbose_assert(count == 1); |
217 |
check_rv(C_FindObjectsFinal(session)); |
218 |
|
219 |
attr[0].type = CKA_VALUE; |
220 |
attr[0].pValue = cert; |
221 |
attr[0].ulValueLen = sizeof(cert); |
222 |
|
223 |
check_rv(C_GetAttributeValue(session, certificate, attr, 1)); |
224 |
|
225 |
printf("Received certificate with length %lu:\n", attr[0].ulValueLen); |
226 |
hex_dump((char*)cert, attr[0].ulValueLen); |
227 |
|
228 |
return verify_sig(sig, sig_len, cert, attr[0].ulValueLen, is_rsa); |
163 |
#else |
229 |
#else |
164 |
return TEST_RV_OK; |
230 |
return TEST_RV_OK; |
165 |
#endif |
231 |
#endif |