• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the License); you may
5  *  not use this file except in compliance with the License.
6  *
7  *  http://www.apache.org/licenses/LICENSE-2.0
8  */
9 
10 
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <gmssl/oid.h>
15 #include <gmssl/x509_alg.h>
16 #include <gmssl/x509_oid.h>
17 #include <gmssl/x509.h>
18 #include <gmssl/rand.h>
19 #include <gmssl/error.h>
20 
21 
test_x509_version(void)22 static int test_x509_version(void)
23 {
24 
25 	int tests[] = {
26 		X509_version_v1,
27 		X509_version_v2,
28 		X509_version_v3,
29 		-1,
30 	};
31 	uint8_t buf[256];
32 	uint8_t *p = buf;
33 	const uint8_t *cp = buf;
34 	size_t len = 0;
35 	size_t i;
36 
37 	format_print(stderr, 0, 0, "Version\n");
38 	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
39 		if (x509_explicit_version_to_der(i, tests[i], &p, &len) < 0) {
40 			error_print();
41 			return -1;
42 		}
43 		format_bytes(stderr, 0, 4, "", buf, len);
44 	}
45 	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
46 		int ver;
47 		if (x509_explicit_version_from_der(i, &ver, &cp, &len) < 0
48 			|| asn1_check(ver == tests[i]) != 1) {
49 			error_print();
50 			return -1;
51 		}
52 		format_print(stderr, 0, 4, "%s\n", x509_version_name(ver));
53 	}
54 	(void)asn1_length_is_zero(len);
55 	printf("%s() ok\n", __FUNCTION__);
56 	return 0;
57 }
58 
59 
test_x509_validity(void)60 static int test_x509_validity(void)
61 {
62 	time_t not_before, not_before_;
63 	time_t not_after, not_after_;
64 	uint8_t buf[256];
65 	uint8_t *p = buf;
66 	const uint8_t *cp = buf;
67 	size_t len = 0;
68 	size_t i;
69 
70 	time(&not_before);
71 
72 	format_print(stderr, 0, 0, "Validity\n");
73 	if (x509_validity_add_days(&not_after, not_before, 365) != 1
74 		|| x509_validity_to_der(not_before, not_after, &p, &len) != 1) {
75 		error_print();
76 		return -1;
77 	}
78 	format_bytes(stderr, 0, 4, "", buf, len);
79 	if (x509_validity_from_der(&not_before_, &not_after_, &cp, &len) != 1
80 		|| asn1_check(not_before == not_before_) != 1
81 		|| asn1_check(not_after == not_after_) != 1
82 		|| asn1_length_is_zero(len) != 1) {
83 		error_print();
84 		return 1;
85 	}
86 	printf("%s() ok\n", __FUNCTION__);
87 	return 0;
88 }
89 
test_x509_attr_type_and_value(void)90 static int test_x509_attr_type_and_value(void)
91 {
92 	int oid;
93 	int tag;
94 	const uint8_t *d;
95 	size_t dlen;
96 	uint8_t buf[256];
97 	uint8_t *p = buf;
98 	const uint8_t *cp = buf;
99 	size_t len = 0;
100 
101 	format_print(stderr, 0, 0, "AttributeTypeAndValue\n");
102 	if (x509_attr_type_and_value_to_der(OID_at_locality_name, ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian"), &p, &len) != 1) {
103 		error_print();
104 		return -1;
105 	}
106 	format_bytes(stderr, 0, 4, "", buf, len);
107 	if (x509_attr_type_and_value_from_der(&oid, &tag, &d, &dlen, &cp, &len) != 1
108 		|| asn1_check(oid == OID_at_locality_name) != 1
109 		|| asn1_check(tag == ASN1_TAG_PrintableString) != 1
110 		|| asn1_check(dlen == strlen("Haidian")) != 1
111 		|| asn1_check(memcmp("Haidian", d, dlen) == 0) != 1
112 		|| asn1_length_is_zero(len) != 1) {
113 		error_print();
114 		return -1;
115 	}
116 	format_print(stderr, 0, 4, "%s : %s ", x509_name_type_name(oid), asn1_tag_name(tag));
117 	format_string(stderr, 0, 0, "", d, dlen);
118 	printf("%s() ok\n", __FUNCTION__);
119 	return 0;
120 }
121 
test_x509_rdn(void)122 static int test_x509_rdn(void)
123 {
124 	int oid;
125 	int tag;
126 	const uint8_t *d;
127 	size_t dlen;
128 	const uint8_t *more;
129 	size_t morelen;
130 	uint8_t buf[256];
131 	uint8_t *p = buf;
132 	const uint8_t *cp = buf;
133 	size_t len = 0;
134 
135 	format_print(stderr, 0, 0, "RDN\n");
136 	if (x509_rdn_to_der(OID_at_locality_name, ASN1_TAG_PrintableString,
137 		(uint8_t *)"Haidian", strlen("Haidian"), NULL, 0, &p, &len) != 1) {
138 		error_print();
139 		return -1;
140 	}
141 	format_bytes(stderr, 0, 4, "", buf, len);
142 	if (x509_rdn_from_der(&oid, &tag, &d, &dlen, &more, &morelen, &cp, &len) != 1
143 		|| asn1_check(oid == OID_at_locality_name) != 1
144 		|| asn1_check(tag == ASN1_TAG_PrintableString) != 1
145 		|| asn1_check(dlen == strlen("Haidian")) != 1
146 		|| asn1_check(memcmp("Haidian", d, dlen) == 0) != 1
147 		|| asn1_check(more == NULL) != 1
148 		|| asn1_check(morelen == 0) != 1
149 		|| asn1_length_is_zero(len) != 1) {
150 		error_print();
151 		return -1;
152 	}
153 	format_print(stderr, 0, 4, "%s : %s ", x509_name_type_name(oid), asn1_tag_name(tag));
154 	format_string(stderr, 0, 0, "", d, dlen);
155 	printf("%s() ok\n", __FUNCTION__);
156 	return 0;
157 }
158 
test_x509_name(void)159 static int test_x509_name(void)
160 {
161 	int err = 0;
162 	uint8_t name[512];
163 	size_t namelen = 0;
164 	uint8_t buf[1024];
165 	const uint8_t *cp = buf;
166 	uint8_t *p = buf;
167 	size_t len = 0;
168 
169 	if (x509_name_add_country_name(name, &namelen, sizeof(name), "CN") != 1
170 		|| format_bytes(stderr, 0, 4, "", name, namelen) > 2
171 		|| x509_name_add_locality_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian")) != 1
172 		|| format_bytes(stderr, 0, 4, "", name, namelen) > 2
173 		|| x509_name_add_state_or_province_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"Beijing", strlen("Beijing")) != 1
174 		|| format_bytes(stderr, 0, 4, "", name, namelen) > 2
175 		|| x509_name_add_organization_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"PKU", strlen("PKU")) != 1
176 		|| format_bytes(stderr, 0, 4, "", name, namelen) > 2
177 		|| x509_name_add_organizational_unit_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"CS", strlen("CS")) != 1
178 		|| format_bytes(stderr, 0, 4, "", name, namelen) > 2
179 		|| x509_name_add_common_name(name, &namelen, sizeof(name), ASN1_TAG_PrintableString, (uint8_t *)"CA", strlen("CA")) != 1
180 		|| format_bytes(stderr, 0, 4, "", name, namelen) > 2
181 		) {
182 		error_print();
183 		return 1;
184 	}
185 	format_bytes(stdout, 0, 0, "der ", name, namelen);
186 	x509_name_print(stdout, 0, 0, "Name", name, namelen);
187 	return 0;
188 }
189 
test_x509_public_key_info(void)190 static int test_x509_public_key_info(void)
191 {
192 	int err = 0;
193 	SM2_KEY sm2_key;
194 	SM2_KEY pub_key;
195 	uint8_t buf[256];
196 	const uint8_t *cp = buf;
197 	uint8_t *p = buf;
198 	size_t len = 0;
199 	const uint8_t *d;
200 	size_t dlen;
201 
202 
203 	if (sm2_key_generate(&sm2_key) != 1
204 		|| x509_public_key_info_to_der(&sm2_key, &p, &len) != 1
205 		|| asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
206 		|| asn1_length_is_zero(len) != 1) {
207 		error_print();
208 		return 1;
209 	}
210 	x509_public_key_info_print(stdout, 0, 0, "PublicKeyInfo", d, dlen);
211 	if (sm2_key_generate(&sm2_key) != 1
212 		|| x509_public_key_info_to_der(&sm2_key, &p, &len) != 1
213 		|| x509_public_key_info_from_der(&pub_key, &cp, &len) != 1
214 		|| asn1_length_is_zero(len) != 1) {
215 		error_print();
216 		return 1;
217 	}
218 	sm2_public_key_print(stdout, 0, 8, "ECPublicKey", &pub_key);
219 
220 	printf("%s() ok\n", __FUNCTION__);
221 	return 0;
222 }
223 
set_x509_name(uint8_t * name,size_t * namelen,size_t maxlen)224 static int set_x509_name(uint8_t *name, size_t *namelen, size_t maxlen)
225 {
226 	*namelen = 0;
227 	if (x509_name_add_country_name(name, namelen, maxlen, "CN") != 1
228 		|| x509_name_add_locality_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"Haidian", strlen("Haidian")) != 1
229 		|| x509_name_add_state_or_province_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"Beijing", strlen("Beijing")) != 1
230 		|| x509_name_add_organization_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"PKU", strlen("PKU")) != 1
231 		|| x509_name_add_organizational_unit_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"CS", strlen("CS")) != 1
232 		|| x509_name_add_common_name(name, namelen, maxlen, ASN1_TAG_PrintableString, (uint8_t *)"CA", strlen("CA")) != 1) {
233 		error_print();
234 		return -1;
235 	}
236 	return 1;
237 }
238 
test_x509_tbs_cert(void)239 static int test_x509_tbs_cert(void)
240 {
241 	uint8_t serial[20] = { 0x01, 0x00 };
242 	size_t serial_len;
243 	uint8_t issuer[256];
244 	size_t issuer_len = 0;
245 	time_t not_before, not_after;
246 	uint8_t subject[256];
247 	size_t subject_len = 0;
248 	SM2_KEY sm2_key;
249 	uint8_t buf[1024] = {0};
250 	uint8_t *p = buf;
251 	const uint8_t *cp = buf;
252 	size_t len = 0;
253 	const uint8_t *d;
254 	size_t dlen;
255 
256 	set_x509_name(issuer, &issuer_len, sizeof(issuer));
257 	time(&not_before);
258 	x509_validity_add_days(&not_after, not_before, 365);
259 	set_x509_name(subject, &subject_len, sizeof(subject));
260 	sm2_key_generate(&sm2_key);
261 
262 	if (x509_tbs_cert_to_der(
263 		X509_version_v3,
264 		serial, sizeof(serial),
265 		OID_sm2sign_with_sm3,
266 		issuer, issuer_len,
267 		not_before, not_after,
268 		subject, subject_len,
269 		&sm2_key,
270 		NULL, 0,
271 		NULL, 0,
272 		NULL, 0,
273 		&p, &len) != 1) {
274 		error_print();
275 		return -1;
276 	}
277 	format_bytes(stderr, 0, 0, "tbs_cert", buf, len);
278 	if (asn1_sequence_from_der(&d, &dlen, &cp, &len) != 1
279 		|| asn1_length_is_zero(len) != 1) {
280 		error_print();
281 		return -1;
282 	}
283 	x509_tbs_cert_print(stderr, 0, 4, "TBSCertificate", d, dlen);
284 
285 	return 0;
286 }
287 
test_x509_cert_get(const uint8_t * cert,size_t certlen)288 static int test_x509_cert_get(const uint8_t *cert, size_t certlen)
289 {
290 	const uint8_t *serial;
291 	size_t serial_len;
292 	const uint8_t *issuer;
293 	size_t issuer_len;
294 	const uint8_t *subject;
295 	size_t subject_len;
296 	SM2_KEY public_key;
297 
298 	if (x509_cert_get_issuer_and_serial_number(cert, certlen, &issuer, &issuer_len, &serial, &serial_len) != 1
299 		|| x509_cert_get_subject(cert, certlen, &subject, &subject_len) != 1
300 		|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) {
301 		error_print();
302 		return -1;
303 	}
304 	format_bytes(stderr, 0, 4, "SerialNumber", serial, serial_len);
305 	x509_name_print(stderr, 0, 4, "Issuer", issuer, issuer_len);
306 	x509_name_print(stderr, 0, 4, "Subject", subject, subject_len);
307 	sm2_public_key_print(stderr, 0, 4, "SubjectPublicKey", &public_key);
308 	return 0;
309 }
310 
test_x509_cert(void)311 static int test_x509_cert(void)
312 {
313 	uint8_t serial[20] = { 0x01, 0x00 };
314 	size_t serial_len;
315 	uint8_t issuer[256];
316 	size_t issuer_len = 0;
317 	time_t not_before, not_after;
318 	uint8_t subject[256];
319 	size_t subject_len = 0;
320 	SM2_KEY sm2_key;
321 	uint8_t cert[1024] = {0};
322 	uint8_t *p = cert;
323 	const uint8_t *cp = cert;
324 	size_t certlen = 0;
325 
326 	set_x509_name(issuer, &issuer_len, sizeof(issuer));
327 	time(&not_before);
328 	x509_validity_add_days(&not_after, not_before, 365);
329 	set_x509_name(subject, &subject_len, sizeof(subject));
330 	sm2_key_generate(&sm2_key);
331 
332 	if (x509_cert_sign(
333 		cert, &certlen, sizeof(cert),
334 		X509_version_v3,
335 		serial, sizeof(serial),
336 		OID_sm2sign_with_sm3,
337 		issuer, issuer_len,
338 		not_before, not_after,
339 		subject, subject_len,
340 		&sm2_key,
341 		NULL, 0,
342 		NULL, 0,
343 		NULL, 0,
344 		&sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) {
345 		error_print();
346 		return -1;
347 	}
348 	format_bytes(stderr, 0, 4, "cert", cert, certlen);
349 	x509_cert_print(stderr, 0, 4, "Certificate", cert, certlen);
350 
351 	if (x509_cert_verify(cert, certlen, &sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) {
352 		error_print();
353 		return -1;
354 	}
355 	printf("x509_cert_verify() success\n");
356 
357 	test_x509_cert_get(cert, certlen);
358 
359 
360 	FILE *fp;
361 
362 	if (!(fp = fopen("cert.pem", "w"))) {
363 		error_print();
364 		return -1;
365 	}
366 
367 	x509_cert_to_pem(cert, certlen, fp);
368 	x509_cert_to_pem(cert, certlen, stderr);
369 	fclose(fp);
370 
371 
372 	if (!(fp = fopen("cert.pem", "r"))) {
373 		error_print();
374 		return -1;
375 	}
376 
377 	memset(cert, 0, sizeof(cert));
378 	if (x509_cert_from_pem(cert, &certlen, sizeof(cert), fp) != 1) {
379 		error_print();
380 		return -1;
381 	}
382 	x509_cert_print(stderr, 0, 4, "Certificate", cert, certlen);
383 
384 	return 0;
385 }
386 
main(void)387 int main(void)
388 {
389 	int err = 0;
390 	err += test_x509_version();
391 	err += test_x509_validity();
392 	err += test_x509_attr_type_and_value();
393 	err += test_x509_rdn();
394 	err += test_x509_name();
395 	err += test_x509_public_key_info();
396 	err += test_x509_tbs_cert();
397 	err += test_x509_cert();
398 	return err;
399 }
400