xref: /openbsd/regress/lib/libcrypto/pem/x509_info.c (revision 9bc7f6d1)
1*9bc7f6d1Stb /*	$OpenBSD: x509_info.c,v 1.2 2020/09/18 14:41:04 tb Exp $	*/
2dd0c637aSschwarze /*
3dd0c637aSschwarze  * Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
4dd0c637aSschwarze  *
5dd0c637aSschwarze  * Permission to use, copy, modify, and distribute this software for any
6dd0c637aSschwarze  * purpose with or without fee is hereby granted, provided that the above
7dd0c637aSschwarze  * copyright notice and this permission notice appear in all copies.
8dd0c637aSschwarze  *
9dd0c637aSschwarze  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10dd0c637aSschwarze  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11dd0c637aSschwarze  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12dd0c637aSschwarze  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13dd0c637aSschwarze  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14dd0c637aSschwarze  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15dd0c637aSschwarze  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16dd0c637aSschwarze  */
17dd0c637aSschwarze 
18dd0c637aSschwarze #include <err.h>
19dd0c637aSschwarze #include <string.h>
20dd0c637aSschwarze 
21dd0c637aSschwarze #include <openssl/bio.h>
22dd0c637aSschwarze #include <openssl/err.h>
23dd0c637aSschwarze #include <openssl/pem.h>
24dd0c637aSschwarze #include <openssl/x509.h>
25dd0c637aSschwarze 
26dd0c637aSschwarze static const char *const bogus_pem = "\
27dd0c637aSschwarze -----BEGIN BOGUS----- \n\
28dd0c637aSschwarze -----END BOGUS----- \n\
29dd0c637aSschwarze ";
30dd0c637aSschwarze 
31dd0c637aSschwarze static const char *const cert_pem = "\
32dd0c637aSschwarze -----BEGIN CERTIFICATE----- \n\
33dd0c637aSschwarze MIIDpTCCAo2gAwIBAgIJAPYm3GvOr5eTMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV \n\
34dd0c637aSschwarze BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT \n\
35dd0c637aSschwarze VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt \n\
36dd0c637aSschwarze ZWRpYXRlIENBMB4XDTE0MDUyNDE0NDUxMVoXDTI0MDQwMTE0NDUxMVowZDELMAkG \n\
37dd0c637aSschwarze A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU \n\
38dd0c637aSschwarze RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgQ2xpZW50IENlcnQw \n\
39dd0c637aSschwarze ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0ranbHRLcLVqN+0BzcZpY \n\
40dd0c637aSschwarze +yOLqxzDWT1LD9eW1stC4NzXX9/DCtSIVyN7YIHdGLrIPr64IDdXXaMRzgZ2rOKs \n\
41dd0c637aSschwarze lmHCAiFpO/ja99gGCJRxH0xwQatqAULfJVHeUhs7OEGOZc2nWifjqKvGfNTilP7D \n\
42dd0c637aSschwarze nwi69ipQFq9oS19FmhwVHk2wg7KZGHI1qDyG04UrfCZMRitvS9+UVhPpIPjuiBi2 \n\
43dd0c637aSschwarze x3/FZIpL5gXJvvFK6xHY63oq2asyzBATntBgnP4qJFWWcvRx24wF1PnZabxuVoL2 \n\
44dd0c637aSschwarze bPnQ/KvONDrw3IdqkKhYNTul7jEcu3OlcZIMw+7DiaKJLAzKb/bBF5gm/pwW6As9 \n\
45dd0c637aSschwarze AgMBAAGjTjBMMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCwGCWCGSAGG \n\
46dd0c637aSschwarze +EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0B \n\
47dd0c637aSschwarze AQUFAAOCAQEAJzA4KTjkjXGSC4He63yX9Br0DneGBzjAwc1H6f72uqnCs8m7jgkE \n\
48dd0c637aSschwarze PQJFdTzQUKh97QPUuayZ2gl8XHagg+iWGy60Kw37gQ0+lumCN2sllvifhHU9R03H \n\
49dd0c637aSschwarze bWtS4kue+yQjMbrzf3zWygMDgwvFOUAIgBpH9qGc+CdNu97INTYd0Mvz51vLlxRn \n\
50dd0c637aSschwarze sC5aBYCWaZFnw3lWYxf9eVFRy9U+DkYFqX0LpmbDtcKP7AZGE6ZwSzaim+Cnoz1u \n\
51dd0c637aSschwarze Cgn+QmpFXgJKMFIZ82iSZISn+JkCCGxctZX1lMvai4Wi8Y0HxW9FTFZ6KBNwwE4B \n\
52dd0c637aSschwarze zjbN/ehBkgLlW/DWfi44DvwUHmuU6QP3cw== \n\
53dd0c637aSschwarze -----END CERTIFICATE----- \n\
54dd0c637aSschwarze ";
55dd0c637aSschwarze 
56dd0c637aSschwarze int
main(void)57dd0c637aSschwarze main(void)
58dd0c637aSschwarze {
59dd0c637aSschwarze 	BIO			*bp;
60dd0c637aSschwarze 	STACK_OF(X509_INFO)	*skin, *skout;
61dd0c637aSschwarze 	X509_INFO		*info0, *info1;
62dd0c637aSschwarze 	const char		*errdata;
63dd0c637aSschwarze 	unsigned long		 errcode;
64dd0c637aSschwarze 	int			 errcount, errflags, num;
65dd0c637aSschwarze 
66dd0c637aSschwarze 	errcount = 0;
67dd0c637aSschwarze 	if ((skin = sk_X509_INFO_new_null()) == NULL)
68dd0c637aSschwarze 		err(1, "sk_X509_INFO_new_null");
69dd0c637aSschwarze 
70dd0c637aSschwarze 	/* Test with empty input. */
71dd0c637aSschwarze 
72dd0c637aSschwarze 	if ((bp = BIO_new_mem_buf("", 0)) == NULL)
73dd0c637aSschwarze 		err(1, "BIO_new_mem_buf(empty)");
74dd0c637aSschwarze 	if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) == NULL)
75dd0c637aSschwarze 		err(1, "empty input: %s",
76dd0c637aSschwarze 		    ERR_error_string(ERR_get_error(), NULL));
77dd0c637aSschwarze 	if (skout != skin)
78dd0c637aSschwarze 		errx(1, "empty input did not return the same stack");
79dd0c637aSschwarze 	skout = NULL;
80dd0c637aSschwarze 	if ((num = sk_X509_INFO_num(skin)) != 0)
81dd0c637aSschwarze 		errx(1, "empty input created %d X509_INFO objects", num);
82dd0c637aSschwarze 	BIO_free(bp);
83dd0c637aSschwarze 
84dd0c637aSschwarze 	/* Test with bogus input. */
85dd0c637aSschwarze 
86dd0c637aSschwarze 	if ((bp = BIO_new_mem_buf(bogus_pem, strlen(bogus_pem))) == NULL)
87dd0c637aSschwarze 		err(1, "BIO_new_mem_buf(bogus_pem)");
88dd0c637aSschwarze 	if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) != NULL)
89dd0c637aSschwarze 		errx(1, "success with bogus input on first try");
90dd0c637aSschwarze 	if ((num = sk_X509_INFO_num(skin)) != 0)
91dd0c637aSschwarze 		errx(1, "bogus input created %d X509_INFO objects", num);
92dd0c637aSschwarze 	if (BIO_reset(bp) != 1)
93dd0c637aSschwarze 		errx(1, "BIO_reset");
94dd0c637aSschwarze 
95dd0c637aSschwarze 	/* Populate stack and test again with bogus input. */
96dd0c637aSschwarze 
97dd0c637aSschwarze 	if ((info0 = X509_INFO_new()) == NULL)
98dd0c637aSschwarze 		err(1, "X509_INFO_new");
99dd0c637aSschwarze 	info0->references = 2;  /* X509_INFO_up_ref(3) doesn't exist. */
100dd0c637aSschwarze 	if (sk_X509_INFO_push(skin, info0) != 1)
101dd0c637aSschwarze 		err(1, "sk_X509_INFO_push");
102dd0c637aSschwarze 	if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) != NULL)
103dd0c637aSschwarze 		errx(1, "success with bogus input on second try");
104dd0c637aSschwarze 	if ((num = sk_X509_INFO_num(skin)) != 1)
105dd0c637aSschwarze 		errx(1, "bogus input changed stack size from 1 to %d", num);
106dd0c637aSschwarze 	if (sk_X509_INFO_value(skin, 0) != info0)
107dd0c637aSschwarze 		errx(1, "bogus input changed stack content");
108dd0c637aSschwarze 	if (info0->references != 2) {
109dd0c637aSschwarze 		warnx("bogus input changed ref count from 2 to %d",
110dd0c637aSschwarze 		    info0->references);
111dd0c637aSschwarze 		info0->references = 2;
112dd0c637aSschwarze 		errcount++;
113dd0c637aSschwarze 	}
114dd0c637aSschwarze 	BIO_free(bp);
115dd0c637aSschwarze 
116dd0c637aSschwarze 	/* Use a real certificate object. */
117dd0c637aSschwarze 
118dd0c637aSschwarze 	if ((bp = BIO_new_mem_buf(cert_pem, strlen(cert_pem))) == NULL)
119dd0c637aSschwarze 		err(1, "BIO_new_mem_buf(cert_pem)");
120dd0c637aSschwarze 	if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) == NULL) {
121dd0c637aSschwarze 		errdata = NULL;
122dd0c637aSschwarze 		errflags = 0;
123dd0c637aSschwarze 		while ((errcode = ERR_get_error_line_data(NULL, NULL,
124dd0c637aSschwarze 		    &errdata, &errflags)) != 0)
125dd0c637aSschwarze 			if (errdata != NULL && (errflags & ERR_TXT_STRING))
126dd0c637aSschwarze 				warnx("%s --- %s",
127dd0c637aSschwarze 				    ERR_error_string(errcode, NULL),
128dd0c637aSschwarze 				    errdata);
129dd0c637aSschwarze 			else
130dd0c637aSschwarze 				warnx("%s", ERR_error_string(errcode, NULL));
131dd0c637aSschwarze 		err(1, "real input: parsing failed");
132dd0c637aSschwarze 	}
133dd0c637aSschwarze 	if (skout != skin)
134dd0c637aSschwarze 		errx(1, "real input did not return the same stack");
135dd0c637aSschwarze 	skout = NULL;
136dd0c637aSschwarze 	if ((num = sk_X509_INFO_num(skin)) != 2)
137dd0c637aSschwarze 		errx(1, "real input changed stack size from 1 to %d", num);
138dd0c637aSschwarze 	if (sk_X509_INFO_value(skin, 0) != info0)
139dd0c637aSschwarze 		errx(1, "real input changed stack content");
140dd0c637aSschwarze 	if (info0->references != 2)
141dd0c637aSschwarze 		errx(1, "real input changed ref count from 2 to %d",
142dd0c637aSschwarze 		    info0->references);
143dd0c637aSschwarze         info1 = sk_X509_INFO_pop(skin);
144dd0c637aSschwarze 	if (info1->x509 == NULL)
145dd0c637aSschwarze 		errx(1, "real input did not create a certificate");
146dd0c637aSschwarze 	X509_INFO_free(info1);
147dd0c637aSschwarze 	info1 = NULL;
148dd0c637aSschwarze 	BIO_free(bp);
149dd0c637aSschwarze 
150dd0c637aSschwarze 	/* Two real certificates followed by bogus input. */
151dd0c637aSschwarze 
152dd0c637aSschwarze 	if ((bp = BIO_new(BIO_s_mem())) == NULL)
153dd0c637aSschwarze 		err(1, "BIO_new");
154dd0c637aSschwarze 	if (BIO_puts(bp, cert_pem) != strlen(cert_pem))
155dd0c637aSschwarze 		err(1, "BIO_puts(cert_pem) first copy");
156dd0c637aSschwarze 	if (BIO_puts(bp, cert_pem) != strlen(cert_pem))
157dd0c637aSschwarze 		err(1, "BIO_puts(cert_pem) second copy");
158dd0c637aSschwarze 	if (BIO_puts(bp, bogus_pem) != strlen(bogus_pem))
159dd0c637aSschwarze 		err(1, "BIO_puts(bogus_pem)");
160dd0c637aSschwarze 	if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) != NULL)
161dd0c637aSschwarze 		errx(1, "success with real + bogus input");
162dd0c637aSschwarze 	if ((num = sk_X509_INFO_num(skin)) != 1) {
163dd0c637aSschwarze 		warnx("real + bogus input changed stack size from 1 to %d",
164dd0c637aSschwarze 		    num);
165dd0c637aSschwarze 		while (sk_X509_INFO_num(skin) > 1)
166*9bc7f6d1Stb 			(void)sk_X509_INFO_pop(skin);
167dd0c637aSschwarze 		errcount++;
168dd0c637aSschwarze 	}
169dd0c637aSschwarze 	if (sk_X509_INFO_value(skin, 0) != info0)
170dd0c637aSschwarze 		errx(1, "real + bogus input changed stack content");
171dd0c637aSschwarze 	if (info0->references != 2) {
172dd0c637aSschwarze 		warnx("real + bogus input changed ref count from 2 to %d",
173dd0c637aSschwarze 		    info0->references);
174dd0c637aSschwarze 		errcount++;
175dd0c637aSschwarze 	}
176dd0c637aSschwarze 	BIO_free(bp);
177dd0c637aSschwarze 	info0->references = 1;
178dd0c637aSschwarze 	X509_INFO_free(info0);
179dd0c637aSschwarze 	sk_X509_INFO_free(skin);
180dd0c637aSschwarze 
181dd0c637aSschwarze 	if (errcount > 0)
182dd0c637aSschwarze 		errx(1, "%d errors detected", errcount);
183dd0c637aSschwarze 	return 0;
184dd0c637aSschwarze }
185