1 /*
2  * Copyright (C) 2017 Red Hat, Inc.
3  *
4  * Author: Nikos Mavrogiannopoulos
5  *
6  * This file is part of GnuTLS.
7  *
8  * GnuTLS is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * GnuTLS is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <assert.h>
30 #include <unistd.h>
31 
32 #include <gnutls/gnutls.h>
33 #include <gnutls/x509.h>
34 #include <gnutls/abstract.h>
35 
36 #include "utils.h"
37 #include "cert-common.h"
38 
crq_check(void)39 static void crq_check(void)
40 {
41 	int ret;
42 	gnutls_x509_crq_t crq;
43 	gnutls_x509_spki_t spki;
44 	gnutls_datum_t tmp;
45 	gnutls_x509_privkey_t privkey;
46 	unsigned salt_size;
47 	gnutls_digest_algorithm_t dig;
48 
49 	ret = global_init();
50 	if (ret != 0) {
51 		fail("%d: %s\n", ret, gnutls_strerror(ret));
52 		exit(1);
53 	}
54 
55 	assert(gnutls_x509_privkey_init(&privkey)>=0);
56 
57 	ret =
58 	    gnutls_x509_privkey_generate(privkey, GNUTLS_PK_RSA, 2048, 0);
59 	assert(ret>=0);
60 
61 	assert(gnutls_x509_spki_init(&spki)>=0);
62 
63 	gnutls_x509_spki_set_rsa_pss_params(spki, GNUTLS_DIG_SHA256, 32);
64 
65 	ret = gnutls_x509_crq_init(&crq);
66 	if (ret < 0) {
67 		fprintf(stderr,
68 			"gnutls_x509_crq_init: %s\n", gnutls_strerror(ret));
69 		exit(1);
70 	}
71 
72 	assert(gnutls_x509_crq_set_version(crq, 1)>=0);
73 	assert(gnutls_x509_crq_set_key(crq, privkey)>=0);
74 	assert(gnutls_x509_crq_set_spki(crq, spki, 0)>=0);
75 
76 	assert(gnutls_x509_crq_set_dn_by_oid(crq, GNUTLS_OID_X520_COMMON_NAME,
77 						0, "CN-Test", 7)>=0);
78 	gnutls_x509_spki_deinit(spki);
79 
80 	assert(gnutls_x509_crq_sign2(crq, privkey, GNUTLS_DIG_SHA256, 0)>=0);
81 
82 	if (debug) {
83 		gnutls_x509_crq_print(crq, GNUTLS_CRT_PRINT_ONELINE, &tmp);
84 
85 		printf("\tCertificate: %.*s\n", tmp.size, tmp.data);
86 		gnutls_free(tmp.data);
87 	}
88 
89 	/* read SPKI */
90 	assert(gnutls_x509_spki_init(&spki)>=0);
91 
92 	ret = gnutls_x509_crq_get_spki(crq, spki, 0);
93 	assert(ret >= 0);
94 
95 	assert(gnutls_x509_spki_get_rsa_pss_params(spki, &dig, &salt_size) >= 0);
96 	assert(salt_size == 32);
97 	assert(dig == GNUTLS_DIG_SHA256);
98 
99 	/* set invalid */
100 	gnutls_x509_spki_set_rsa_pss_params(spki, GNUTLS_DIG_SHA256, 1024);
101 	assert(gnutls_x509_crq_set_spki(crq, spki, 0) == GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
102 
103 	gnutls_x509_crq_deinit(crq);
104 	gnutls_x509_spki_deinit(spki);
105 	gnutls_x509_privkey_deinit(privkey);
106 	gnutls_global_deinit();
107 }
108 
109 
cert_check(void)110 static void cert_check(void)
111 {
112 	int ret;
113 	gnutls_x509_crt_t crt;
114 	gnutls_x509_spki_t spki;
115 	gnutls_datum_t tmp;
116 	unsigned salt_size;
117 	gnutls_digest_algorithm_t dig;
118 
119 	ret = global_init();
120 	if (ret != 0) {
121 		fail("%d: %s\n", ret, gnutls_strerror(ret));
122 		exit(1);
123 	}
124 
125 	ret = gnutls_x509_spki_init(&spki);
126 	assert(ret>=0);
127 
128 	ret = gnutls_x509_crt_init(&crt);
129 	if (ret < 0) {
130 		fprintf(stderr,
131 			"gnutls_x509_crt_init: %s\n", gnutls_strerror(ret));
132 		exit(1);
133 	}
134 
135 	ret =
136 	    gnutls_x509_crt_import(crt, &server_ca3_rsa_pss2_cert,
137 				   GNUTLS_X509_FMT_PEM);
138 	if (ret < 0) {
139 		fprintf(stderr,
140 			"gnutls_x509_crt_import: %s\n", gnutls_strerror(ret));
141 		exit(1);
142 	}
143 
144 	if (debug) {
145 		gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_ONELINE, &tmp);
146 
147 		printf("\tCertificate: %.*s\n", tmp.size, tmp.data);
148 		gnutls_free(tmp.data);
149 	}
150 
151 	ret = gnutls_x509_crt_get_spki(crt, spki, 0);
152 	assert(ret >= 0);
153 
154 	assert(gnutls_x509_spki_get_rsa_pss_params(spki, &dig, &salt_size) >= 0);
155 	assert(salt_size == 32);
156 	assert(dig == GNUTLS_DIG_SHA256);
157 
158 	/* set invalid */
159 	gnutls_x509_spki_set_rsa_pss_params(spki, GNUTLS_DIG_SHA256, 1024);
160 	assert(gnutls_x509_crt_set_spki(crt, spki, 0) == GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
161 
162 	gnutls_x509_crt_deinit(crt);
163 	gnutls_x509_spki_deinit(spki);
164 	gnutls_global_deinit();
165 }
166 
key_check(void)167 static void key_check(void)
168 {
169 	int ret;
170 	gnutls_x509_privkey_t key;
171 	gnutls_x509_spki_t spki;
172 	unsigned salt_size;
173 	gnutls_digest_algorithm_t dig;
174 
175 	ret = global_init();
176 	if (ret != 0) {
177 		fail("%d: %s\n", ret, gnutls_strerror(ret));
178 		exit(1);
179 	}
180 
181 	ret = gnutls_x509_spki_init(&spki);
182 	assert(ret>=0);
183 
184 	ret = gnutls_x509_privkey_init(&key);
185 	if (ret < 0) {
186 		fprintf(stderr,
187 			"gnutls_x509_privkey_init: %s\n", gnutls_strerror(ret));
188 		exit(1);
189 	}
190 
191 	ret =
192 	    gnutls_x509_privkey_import(key, &server_ca3_rsa_pss2_key,
193 				       GNUTLS_X509_FMT_PEM);
194 	if (ret < 0) {
195 		fprintf(stderr,
196 			"gnutls_x509_privkey_import: %s\n",
197 			gnutls_strerror(ret));
198 		exit(1);
199 	}
200 
201 	ret = gnutls_x509_privkey_get_spki(key, spki, 0);
202 	assert(ret >= 0);
203 
204 	assert(gnutls_x509_spki_get_rsa_pss_params(spki, &dig, &salt_size) >= 0);
205 	assert(salt_size == 32);
206 	assert(dig == GNUTLS_DIG_SHA256);
207 
208 	/* set and get */
209 	gnutls_x509_spki_set_rsa_pss_params(spki, GNUTLS_DIG_SHA1, 64);
210 	assert(gnutls_x509_spki_get_rsa_pss_params(spki, &dig, &salt_size) >= 0);
211 	assert(salt_size == 64);
212 	assert(dig == GNUTLS_DIG_SHA1);
213 
214 	/* set invalid */
215 	gnutls_x509_spki_set_rsa_pss_params(spki, GNUTLS_DIG_SHA1, 1024);
216 	assert(gnutls_x509_privkey_set_spki(key, spki, 0) == GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
217 
218 	gnutls_x509_privkey_deinit(key);
219 	gnutls_x509_spki_deinit(spki);
220 }
221 
doit(void)222 void doit(void)
223 {
224 	cert_check();
225 	key_check();
226 	crq_check();
227 }
228