2 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
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.
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.
18 * You should have received a copy of the GNU General Public License
19 * along with GnuTLS; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26 #include <gnutls/x509.h>
28 #define MAX_FILE_SIZE 16*1024
36 static struct file_res test_files
[] = {
38 {"test2.pem", GNUTLS_CERT_NOT_TRUSTED
},
39 {"test3.pem", GNUTLS_CERT_INVALID
| GNUTLS_CERT_NOT_TRUSTED
},
41 {"test13.pem", GNUTLS_CERT_INVALID
| GNUTLS_CERT_NOT_TRUSTED
},
42 {"test20.pem", GNUTLS_CERT_REVOKED
| GNUTLS_CERT_NOT_TRUSTED
},
43 {"test21.pem", GNUTLS_CERT_REVOKED
| GNUTLS_CERT_NOT_TRUSTED
},
44 {"test22.pem", GNUTLS_CERT_INVALID
| GNUTLS_CERT_NOT_TRUSTED
},
45 {"test23.pem", GNUTLS_CERT_INVALID
| GNUTLS_CERT_NOT_TRUSTED
},
47 {"test25.pem", GNUTLS_CERT_INVALID
| GNUTLS_CERT_NOT_TRUSTED
},
52 #define CA_FILE "ca.pem"
54 int _verify_x509_file (const char *certfile
, const char *cafile
);
60 if (x
& GNUTLS_CERT_INVALID
)
61 printf ("- certificate is invalid\n");
63 printf ("- certificate is valid\n");
64 if (x
& GNUTLS_CERT_NOT_TRUSTED
)
65 printf ("- certificate is NOT trusted\n");
67 printf ("- certificate is trusted\n");
69 if (x
& GNUTLS_CERT_CORRUPTED
)
70 printf ("- Found a corrupted certificate.\n");
72 if (x
& GNUTLS_CERT_REVOKED
)
73 printf ("- certificate is revoked.\n");
82 int i
= 0, exp_result
;
84 gnutls_global_init ();
87 "This test will perform some checks on X.509 certificate\n");
88 fprintf (stderr
, "verification functions.\n\n");
92 exp_result
= test_files
[i
].result
;
93 file
= test_files
[i
++].test_file
;
97 x
= _verify_x509_file (file
, CA_FILE
);
101 fprintf (stderr
, "Unexpected error: %d\n", x
);
104 printf ("Test %d, file %s: ", i
, file
);
108 printf ("failed.\n");
110 fprintf (stderr
, "Unexpected error in verification.\n");
111 fprintf (stderr
, "Certificate was found to be: \n");
124 gnutls_global_deinit ();
130 #define CERT_SEP "-----BEGIN CERT"
131 #define CRL_SEP "-----BEGIN X509 CRL"
133 /* Verifies a base64 encoded certificate list from memory
136 _verify_x509_mem (const char *cert
, int cert_size
,
137 const char *ca
, int ca_size
, const char *crl
, int crl_size
)
144 gnutls_x509_crt
*x509_cert_list
= NULL
;
145 gnutls_x509_crt x509_ca
;
146 gnutls_x509_crl
*x509_crl_list
= NULL
;
147 int x509_ncerts
, x509_ncrls
;
149 /* Decode the CA certificate
151 tmp
.data
= (char *) ca
;
154 ret
= gnutls_x509_crt_init (&x509_ca
);
157 fprintf (stderr
, "Error parsing the CA certificate: %s\n",
158 gnutls_strerror (ret
));
162 ret
= gnutls_x509_crt_import (x509_ca
, &tmp
, GNUTLS_X509_FMT_PEM
);
166 fprintf (stderr
, "Error parsing the CA certificate: %s\n",
167 gnutls_strerror (ret
));
171 /* Decode the CRL list
178 if (strstr (ptr
, CRL_SEP
) != NULL
) /* if CRLs exist */
182 (gnutls_x509_crl
*) realloc (x509_crl_list
,
183 i
* sizeof (gnutls_x509_crl
));
184 if (x509_crl_list
== NULL
)
186 fprintf (stderr
, "memory error\n");
190 tmp
.data
= (char *) ptr
;
193 ret
= gnutls_x509_crl_init (&x509_crl_list
[i
- 1]);
196 fprintf (stderr
, "Error parsing the CRL[%d]: %s\n", i
,
197 gnutls_strerror (ret
));
202 gnutls_x509_crl_import (x509_crl_list
[i
- 1], &tmp
,
203 GNUTLS_X509_FMT_PEM
);
206 fprintf (stderr
, "Error parsing the CRL[%d]: %s\n", i
,
207 gnutls_strerror (ret
));
211 /* now we move ptr after the pem header */
212 ptr
= strstr (ptr
, CRL_SEP
);
218 while ((ptr
= strstr (ptr
, CRL_SEP
)) != NULL
);
223 /* Decode the certificate chain.
233 (gnutls_x509_crt
*) realloc (x509_cert_list
,
234 i
* sizeof (gnutls_x509_crt
));
235 if (x509_cert_list
== NULL
)
237 fprintf (stderr
, "memory error\n");
241 tmp
.data
= (char *) ptr
;
244 ret
= gnutls_x509_crt_init (&x509_cert_list
[i
- 1]);
247 fprintf (stderr
, "Error parsing the certificate[%d]: %s\n", i
,
248 gnutls_strerror (ret
));
253 gnutls_x509_crt_import (x509_cert_list
[i
- 1], &tmp
,
254 GNUTLS_X509_FMT_PEM
);
257 fprintf (stderr
, "Error parsing the certificate[%d]: %s\n", i
,
258 gnutls_strerror (ret
));
262 /* now we move ptr after the pem header */
263 ptr
= strstr (ptr
, CERT_SEP
);
269 while ((ptr
= strstr (ptr
, CERT_SEP
)) != NULL
);
273 ret
= gnutls_x509_crt_list_verify (x509_cert_list
, x509_ncerts
,
274 &x509_ca
, 1, x509_crl_list
, x509_ncrls
,
277 gnutls_x509_crt_deinit (x509_ca
);
279 for (i
= 0; i
< x509_ncerts
; i
++)
281 gnutls_x509_crt_deinit (x509_cert_list
[i
]);
284 for (i
= 0; i
< x509_ncrls
; i
++)
286 gnutls_x509_crl_deinit (x509_crl_list
[i
]);
289 free (x509_cert_list
);
290 free (x509_crl_list
);
294 fprintf (stderr
, "Error in verification: %s\n", gnutls_strerror (ret
));
303 /* Reads and verifies a base64 encoded certificate file
306 _verify_x509_file (const char *certfile
, const char *cafile
)
308 int ca_size
, cert_size
;
309 char ca
[MAX_FILE_SIZE
];
310 char cert
[MAX_FILE_SIZE
];
313 fd1
= fopen (certfile
, "rb");
316 fprintf (stderr
, "error opening %s\n", certfile
);
317 return GNUTLS_E_FILE_ERROR
;
320 cert_size
= fread (cert
, 1, sizeof (cert
) - 1, fd1
);
326 fd1
= fopen (cafile
, "rb");
329 fprintf (stderr
, "error opening %s\n", cafile
);
330 return GNUTLS_E_FILE_ERROR
;
333 ca_size
= fread (ca
, 1, sizeof (ca
) - 1, fd1
);
338 return _verify_x509_mem (cert
, cert_size
, ca
, ca_size
, cert
, cert_size
);