• 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 <stdint.h>
15 #include <assert.h>
16 #include <gmssl/sm2.h>
17 #include <gmssl/oid.h>
18 #include <gmssl/pem.h>
19 #include <gmssl/asn1.h>
20 #include <gmssl/x509_str.h>
21 #include <gmssl/error.h>
22 
23 /*
24 DirectoryString ::= CHOICE {
25 	teletexString		TeletexString (SIZE (1..MAX)),
26 	printableString 	PrintableString (SIZE (1..MAX)),
27 	universalString		UniversalString (SIZE (1..MAX)),
28 	utf8String		UTF8String (SIZE (1..MAX)),
29 	bmpString		BMPString (SIZE (1..MAX)) }
30 
31 BMPString has zeros!
32 	"Cert" in BMPStirng is 00 43 00 65 00 72 00 74
33 
34 RDN 中很多值都是这个类型,但是有特定的长度限制,因此这个函数应该增加一个长度限制选项。
35 */
36 
37 
x509_directory_name_check(int tag,const uint8_t * d,size_t dlen)38 int x509_directory_name_check(int tag, const uint8_t *d, size_t dlen)
39 {
40 	switch (tag) {
41 	case ASN1_TAG_TeletexString:
42 	case ASN1_TAG_PrintableString:
43 	case ASN1_TAG_UniversalString:
44 	case ASN1_TAG_UTF8String:
45 		if (d && strnlen((char *)d, dlen) != dlen) {
46 			error_print();
47 			return -1;
48 		}
49 		break;
50 	case ASN1_TAG_BMPString:
51 		if (d && dlen % 2) {
52 			error_print();
53 			return -1;
54 		}
55 		break;
56 	default:
57 		error_print();
58 		return -1;
59 	}
60 	return 1;
61 }
62 
x509_directory_name_check_ex(int tag,const uint8_t * d,size_t dlen,size_t minlen,size_t maxlen)63 int x509_directory_name_check_ex(int tag, const uint8_t *d, size_t dlen, size_t minlen, size_t maxlen)
64 {
65 	if (x509_directory_name_check(tag, d, dlen) != 1) {
66 		error_print();
67 		return -1;
68 	}
69 	if (dlen < minlen || dlen > maxlen) {
70 		printf("%s %d: dlen = %zu, minlen = %zu, maxlne = %zu\n", __FILE__, __LINE__, dlen, minlen, maxlen);
71 		error_print();
72 		return -1;
73 	}
74 	return 1;
75 }
76 
x509_directory_name_to_der(int tag,const uint8_t * d,size_t dlen,uint8_t ** out,size_t * outlen)77 int x509_directory_name_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
78 {
79 	int ret;
80 	if (x509_directory_name_check(tag, d, dlen) != 1) {
81 		error_print();
82 		return -1;
83 	}
84 	if ((ret = asn1_type_to_der(tag, d, dlen, out, outlen)) != 1) {
85 		if (ret < 0) error_print();
86 		return ret;
87 	}
88 	return 1;
89 }
90 
x509_directory_name_from_der(int * tag,const uint8_t ** d,size_t * dlen,const uint8_t ** in,size_t * inlen)91 int x509_directory_name_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
92 {
93 	int ret;
94 
95 	if ((ret = asn1_tag_get(tag, in, inlen)) != 1) {
96 		if (ret < 0) error_print();
97 		return ret;
98 	}
99 	switch (*tag) {
100 	case ASN1_TAG_TeletexString:
101 	case ASN1_TAG_PrintableString:
102 	case ASN1_TAG_UniversalString:
103 	case ASN1_TAG_UTF8String:
104 	case ASN1_TAG_BMPString:
105 		break;
106 	default:
107 		return 0;
108 	}
109 
110 	if ((ret = asn1_any_type_from_der(tag, d, dlen, in, inlen)) != 1) {
111 		if (ret < 0) error_print();
112 		return ret;
113 	}
114 	if (x509_directory_name_check(*tag, *d, *dlen) != 1) {
115 		error_print();
116 		return -1;
117 	}
118 	return 1;
119 }
120 
x509_explicit_directory_name_to_der(int index,int tag,const uint8_t * d,size_t dlen,uint8_t ** out,size_t * outlen)121 int x509_explicit_directory_name_to_der(int index, int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
122 {
123 	int ret;
124 	size_t len = 0;
125 
126 	if ((ret = x509_directory_name_to_der(tag, d, dlen, NULL, &len)) != 1) {
127 		if (ret < 0) error_print();
128 		return ret;
129 	}
130 	if (asn1_explicit_header_to_der(index, len, out, outlen) != 1
131 		|| x509_directory_name_to_der(tag, d, dlen, out, outlen) != 1) {
132 		error_print();
133 		return -1;
134 	}
135 	return 1;
136 }
137 
x509_explicit_directory_name_from_der(int index,int * tag,const uint8_t ** d,size_t * dlen,const uint8_t ** in,size_t * inlen)138 int x509_explicit_directory_name_from_der(int index, int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
139 {
140 	int ret;
141 	const uint8_t *p;
142 	size_t len;
143 
144 	if ((ret = asn1_explicit_from_der(index, &p, &len, in, inlen)) != 1) {
145 		if (ret < 0) error_print();
146 		return ret;
147 	}
148 	if (x509_directory_name_from_der(tag, d, dlen, &p, &len) != 1
149 		|| asn1_length_is_zero(len) != 1) {
150 		error_print();
151 		return -1;
152 	}
153 	return 1;
154 }
155 
x509_directory_name_print(FILE * fp,int fmt,int ind,const char * label,int tag,const uint8_t * d,size_t dlen)156 int x509_directory_name_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen)
157 {
158 	return asn1_string_print(fp, fmt, ind, label, tag, d, dlen);
159 }
160 
x509_display_text_check(int tag,const uint8_t * d,size_t dlen)161 int x509_display_text_check(int tag, const uint8_t *d, size_t dlen)
162 {
163 	switch (tag) {
164 	case ASN1_TAG_IA5String:
165 	case ASN1_TAG_VisibleString:
166 	case ASN1_TAG_UTF8String:
167 		if (d && strnlen((char *)d, dlen) != dlen) {
168 			error_print();
169 			return -1;
170 		}
171 		break;
172 	case ASN1_TAG_BMPString:
173 		if (d && dlen % 2) {
174 			error_print();
175 			return -1;
176 		}
177 		break;
178 	default:
179 		error_print();
180 		return -1;
181 	}
182 	if (dlen < X509_DISPLAY_TEXT_MIN_LEN || dlen > X509_DISPLAY_TEXT_MAX_LEN) {
183 		error_print();
184 		return -1;
185 	}
186 	return 1;
187 }
188 
x509_display_text_to_der(int tag,const uint8_t * d,size_t dlen,uint8_t ** out,size_t * outlen)189 int x509_display_text_to_der(int tag, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
190 {
191 	int ret;
192 	if (x509_display_text_check(tag, d, dlen) != 1) {
193 		error_print();
194 		return -1;
195 	}
196 	if ((ret = asn1_type_to_der(tag, d, dlen, out, outlen)) != 1) {
197 		if (ret < 0) error_print();
198 		return ret;
199 	}
200 	return 1;
201 }
202 
x509_display_text_from_der(int * tag,const uint8_t ** d,size_t * dlen,const uint8_t ** in,size_t * inlen)203 int x509_display_text_from_der(int *tag, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
204 {
205 	int ret;
206 
207 	if ((ret = asn1_tag_get(tag, in, inlen)) != 1) {
208 		if (ret < 0) error_print();
209 		return ret;
210 	}
211 	switch (*tag) {
212 	case ASN1_TAG_IA5String:
213 	case ASN1_TAG_VisibleString:
214 	case ASN1_TAG_UTF8String:
215 	case ASN1_TAG_BMPString:
216 		break;
217 	default:
218 		return 0;
219 	}
220 
221 	if ((ret = asn1_any_type_from_der(tag, d, dlen, in, inlen)) != 1) {
222 		if (ret < 0) error_print();
223 		return ret;
224 	}
225 	if (x509_display_text_check(*tag, *d, *dlen) != 1) {
226 		error_print();
227 		return -1;
228 	}
229 	return 1;
230 }
231 
x509_display_text_print(FILE * fp,int fmt,int ind,const char * label,int tag,const uint8_t * d,size_t dlen)232 int x509_display_text_print(FILE *fp, int fmt, int ind, const char *label, int tag, const uint8_t *d, size_t dlen)
233 {
234 	return asn1_string_print(fp, fmt, ind, label, tag, d, dlen);
235 }
236