1/** 2 * \file x509.h 3 * 4 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 5 * 6 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org> 7 * 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * * Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * * Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * * Neither the names of PolarSSL or XySSL nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35#ifndef POLARSSL_X509_H 36#define POLARSSL_X509_H 37 38#include "polarssl/rsa.h" 39 40#define POLARSSL_ERR_ASN1_OUT_OF_DATA -0x0014 41#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG -0x0016 42#define POLARSSL_ERR_ASN1_INVALID_LENGTH -0x0018 43#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH -0x001A 44#define POLARSSL_ERR_ASN1_INVALID_DATA -0x001C 45 46#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x0020 47#define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x0040 48#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x0060 49#define POLARSSL_ERR_X509_CERT_INVALID_VERSION -0x0080 50#define POLARSSL_ERR_X509_CERT_INVALID_SERIAL -0x00A0 51#define POLARSSL_ERR_X509_CERT_INVALID_ALG -0x00C0 52#define POLARSSL_ERR_X509_CERT_INVALID_NAME -0x00E0 53#define POLARSSL_ERR_X509_CERT_INVALID_DATE -0x0100 54#define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY -0x0120 55#define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE -0x0140 56#define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS -0x0160 57#define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION -0x0180 58#define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG -0x01A0 59#define POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG -0x01C0 60#define POLARSSL_ERR_X509_CERT_SIG_MISMATCH -0x01E0 61#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x0200 62#define POLARSSL_ERR_X509_KEY_INVALID_PEM -0x0220 63#define POLARSSL_ERR_X509_KEY_INVALID_VERSION -0x0240 64#define POLARSSL_ERR_X509_KEY_INVALID_FORMAT -0x0260 65#define POLARSSL_ERR_X509_KEY_INVALID_ENC_IV -0x0280 66#define POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG -0x02A0 67#define POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED -0x02C0 68#define POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH -0x02E0 69#define POLARSSL_ERR_X509_POINT_ERROR -0x0300 70#define POLARSSL_ERR_X509_VALUE_TO_LENGTH -0x0320 71 72#define BADCERT_EXPIRED 1 73#define BADCERT_REVOKED 2 74#define BADCERT_CN_MISMATCH 4 75#define BADCERT_NOT_TRUSTED 8 76 77/* 78 * DER constants 79 */ 80#define ASN1_BOOLEAN 0x01 81#define ASN1_INTEGER 0x02 82#define ASN1_BIT_STRING 0x03 83#define ASN1_OCTET_STRING 0x04 84#define ASN1_NULL 0x05 85#define ASN1_OID 0x06 86#define ASN1_UTF8_STRING 0x0C 87#define ASN1_SEQUENCE 0x10 88#define ASN1_SET 0x11 89#define ASN1_PRINTABLE_STRING 0x13 90#define ASN1_T61_STRING 0x14 91#define ASN1_IA5_STRING 0x16 92#define ASN1_UTC_TIME 0x17 93#define ASN1_UNIVERSAL_STRING 0x1C 94#define ASN1_BMP_STRING 0x1E 95#define ASN1_PRIMITIVE 0x00 96#define ASN1_CONSTRUCTED 0x20 97#define ASN1_CONTEXT_SPECIFIC 0x80 98 99/* 100 * various object identifiers 101 */ 102#define X520_COMMON_NAME 3 103#define X520_COUNTRY 6 104#define X520_LOCALITY 7 105#define X520_STATE 8 106#define X520_ORGANIZATION 10 107#define X520_ORG_UNIT 11 108#define PKCS9_EMAIL 1 109 110#define X509_OUTPUT_DER 0x01 111#define X509_OUTPUT_PEM 0x02 112#define PEM_LINE_LENGTH 72 113#define X509_ISSUER 0x01 114#define X509_SUBJECT 0x02 115 116#define OID_X520 "\x55\x04" 117#define OID_CN "\x55\x04\x03" 118#define OID_PKCS1 "\x2A\x86\x48\x86\xF7\x0D\x01\x01" 119#define OID_PKCS1_RSA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01" 120#define OID_PKCS1_RSA_SHA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05" 121#define OID_PKCS9 "\x2A\x86\x48\x86\xF7\x0D\x01\x09" 122#define OID_PKCS9_EMAIL "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" 123 124/* 125 * Structures for parsing X.509 certificates 126 */ 127typedef struct _x509_buf 128{ 129 int tag; 130 int len; 131 unsigned char *p; 132} 133x509_buf; 134 135typedef struct _x509_name 136{ 137 x509_buf oid; 138 x509_buf val; 139 struct _x509_name *next; 140} 141x509_name; 142 143typedef struct _x509_time 144{ 145 int year, mon, day; 146 int hour, min, sec; 147} 148x509_time; 149 150typedef struct _x509_cert 151{ 152 x509_buf raw; 153 x509_buf tbs; 154 155 int version; 156 x509_buf serial; 157 x509_buf sig_oid1; 158 159 x509_buf issuer_raw; 160 x509_buf subject_raw; 161 162 x509_name issuer; 163 x509_name subject; 164 165 x509_time valid_from; 166 x509_time valid_to; 167 168 x509_buf pk_oid; 169 rsa_context rsa; 170 171 x509_buf issuer_id; 172 x509_buf subject_id; 173 x509_buf v3_ext; 174 175 int ca_istrue; 176 int max_pathlen; 177 178 x509_buf sig_oid2; 179 x509_buf sig; 180 181 struct _x509_cert *next; 182} 183x509_cert; 184 185/* 186 * Structures for writing X.509 certificates 187 */ 188typedef struct _x509_node 189{ 190 unsigned char *data; 191 unsigned char *p; 192 unsigned char *end; 193 194 size_t len; 195} 196x509_node; 197 198typedef struct _x509_raw 199{ 200 x509_node raw; 201 x509_node tbs; 202 203 x509_node version; 204 x509_node serial; 205 x509_node tbs_signalg; 206 x509_node issuer; 207 x509_node validity; 208 x509_node subject; 209 x509_node subpubkey; 210 211 x509_node signalg; 212 x509_node sign; 213} 214x509_raw; 215 216#ifdef __cplusplus 217extern "C" { 218#endif 219 220/** 221 * \brief Parse one or more certificates and add them 222 * to the chained list 223 * 224 * \param chain points to the start of the chain 225 * \param buf buffer holding the certificate data 226 * \param buflen size of the buffer 227 * 228 * \return 0 if successful, or a specific X509 error code 229 */ 230int x509parse_crt( x509_cert *crt, unsigned char *buf, int buflen ); 231 232/** 233 * \brief Load one or more certificates and add them 234 * to the chained list 235 * 236 * \param chain points to the start of the chain 237 * \param path filename to read the certificates from 238 * 239 * \return 0 if successful, or a specific X509 error code 240 */ 241int x509parse_crtfile( x509_cert *crt, char *path ); 242 243/** 244 * \brief Parse a private RSA key 245 * 246 * \param rsa RSA context to be initialized 247 * \param buf input buffer 248 * \param buflen size of the buffer 249 * \param pwd password for decryption (optional) 250 * \param pwdlen size of the password 251 * 252 * \return 0 if successful, or a specific X509 error code 253 */ 254int x509parse_key( rsa_context *rsa, 255 unsigned char *buf, int buflen, 256 unsigned char *pwd, int pwdlen ); 257 258/** 259 * \brief Load and parse a private RSA key 260 * 261 * \param rsa RSA context to be initialized 262 * \param path filename to read the private key from 263 * \param pwd password to decrypt the file (can be NULL) 264 * 265 * \return 0 if successful, or a specific X509 error code 266 */ 267int x509parse_keyfile( rsa_context *rsa, char *path, char *password ); 268 269/** 270 * \brief Store the certificate DN in printable form into buf; 271 * no more than (end - buf) characters will be written. 272 */ 273int x509parse_dn_gets( char *buf, char *end, x509_name *dn ); 274 275/** 276 * \brief Returns an informational string about the 277 * certificate. 278 */ 279char *x509parse_cert_info( char *prefix, x509_cert *crt ); 280 281/** 282 * \brief Return 0 if the certificate is still valid, 283 * or BADCERT_EXPIRED 284 */ 285int x509parse_expired( x509_cert *crt ); 286 287/** 288 * \brief Verify the certificate signature 289 * 290 * \param crt a certificate to be verified 291 * \param trust_ca the trusted CA chain 292 * \param cn expected Common Name (can be set to 293 * NULL if the CN must not be verified) 294 * \param flags result of the verification 295 * 296 * \return 0 if successful or POLARSSL_ERR_X509_SIG_VERIFY_FAILED, 297 * in which case *flags will have one or more of 298 * the following values set: 299 * BADCERT_EXPIRED -- 300 * BADCERT_REVOKED -- 301 * BADCERT_CN_MISMATCH -- 302 * BADCERT_NOT_TRUSTED 303 * 304 * \note TODO: add two arguments, depth and crl 305 */ 306int x509parse_verify( x509_cert *crt, 307 x509_cert *trust_ca, 308 char *cn, int *flags ); 309 310/** 311 * \brief Unallocate all certificate data 312 */ 313void x509_free( x509_cert *crt ); 314 315/** 316 * \brief Checkup routine 317 * 318 * \return 0 if successful, or 1 if the test failed 319 */ 320int x509_self_test( int verbose ); 321 322/** 323 * \brief Write a certificate info file 324 * 325 * \param chain points to the raw certificate data 326 * \param path filename to write the certificate to 327 * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM 328 * 329 * \return 0 if successful, or a specific X509 error code 330 */ 331int x509write_crtfile( x509_raw *chain, 332 unsigned char *path, 333 int format ); 334 335/** 336 * \brief Write a certificate signing request message format file 337 * 338 * \param chain points to the raw certificate (with x509write_create_csr) data 339 * \param path filename to write the certificate to 340 * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM 341 * 342 * \return 0 if successful, or a specific X509 error code 343 */ 344int x509write_csrfile( x509_raw *chain, 345 unsigned char *path, 346 int format ); 347 348/* 349 * \brief Write a private RSA key into a file 350 * 351 * \param rsa points to an RSA key 352 * \param path filename to write the key to 353 * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM 354 * 355 * \return 0 if successful, or a specific X509 error code 356 */ 357int x509write_keyfile( rsa_context *rsa, 358 char *path, 359 int format ); 360 361/** 362 * \brief Add a public key to certificate 363 * 364 * \param chain points to the raw certificate data 365 * \param pubkey points to an RSA key 366 * 367 * \return 0 if successful, or a specific X509 error code 368 */ 369int x509write_add_pubkey( x509_raw *chain, rsa_context *pubkey ); 370 371/** 372 * \brief Create x509 subject/issuer field to raw certificate 373 * from string or CA cert. Make string NULL if you will 374 * use the CA copy function or make CA NULL then used 375 * the string parse. 376 * 377 * \param chain points to the raw certificate data 378 * \param names a string that can hold (separete with ";"): 379 * CN=CommonName 380 * -- O=Organization 381 * -- OU=OrgUnit 382 * -- ST=State 383 * -- L=Locality 384 * -- R=Email 385 * -- C=Country 386 * . Make that NULL if you didn't need that. 387 * \param flag flag is X509_ISSUER or X509_SUBJECT that defined 388 * where change 389 * \param ca the certificate for copy data. Make that NULL if you 390 * didn't need that. 391 * \param ca_flag set the ca field from copy to crt 392 * 393 * \return 0 if successful, or a specific X509 error code 394 */ 395int x509write_add_customize ( x509_raw *crt, 396 unsigned char *names, 397 int flag, 398 x509_cert *ca, 399 int ca_flag ); 400 401/** 402* \brief Add x509 issuer field 403* 404* \param chain points to the raw certificate data 405* \param issuer a string holding (separete with ";"): 406* CN=CommonName 407* -- O=Organization 408* -- OU=OrgUnit 409* -- ST=State 410* -- L=Locality 411* -- R=Email 412* -- C=Country 413* . Set this to NULL if not needed. 414* \return 0 if successful, or a specific X509 error code 415*/ 416int x509write_add_issuer( x509_raw *crt, unsigned char *issuer); 417 418/** 419 * \brief Add x509 subject field 420 * 421 * \param chain points to the raw certificate data 422 * \param subject a string holding (separete with ";"): 423 * CN=CommonName 424 * -- O=Organization 425 * -- OU=OrgUnit 426 * -- ST=State 427 * -- L=Locality 428 * -- R=Email 429 * -- C=Country 430 * . Set this to NULL if not needed. 431 * \return 0 if successful, or a specific X509 error code 432 */ 433int x509write_add_subject( x509_raw *crt, unsigned char *subject); 434 435/** 436* \brief Copy x509 issuer field from another certificate 437* 438* \param chain points to the raw certificate data 439* \param from_crt the certificate whose issuer is to be copied. 440* \return 0 if successful, or a specific X509 error code 441*/ 442int x509write_copy_issuer(x509_raw *crt, x509_cert *from_crt); 443 444/** 445* \brief Copy x509 subject field from another certificate 446* 447* \param chain points to the raw certificate data 448* \param from_crt the certificate whose subject is to be copied. 449* \return 0 if successful, or a specific X509 error code 450*/ 451int x509write_copy_subject(x509_raw *crt, x509_cert *from_crt); 452 453/** 454* \brief Copy x509 issuer field from the subject of another certificate 455* 456* \param chain points to the raw certificate data 457* \param from_crt the certificate whose subject is to be copied. 458* \return 0 if successful, or a specific X509 error code 459*/ 460int x509write_copy_issuer_from_subject(x509_raw *crt, x509_cert *from_crt); 461 462/** 463* \brief Copy x509 subject field from the issuer of another certificate 464* 465* \param chain points to the raw certificate data 466* \param from_crt the certificate whose issuer is to be copied. 467* \return 0 if successful, or a specific X509 error code 468*/ 469int x509write_copy_subject_from_issuer(x509_raw *crt, x509_cert *from_crt); 470 471/** 472 * \brief Create x509 validity time in UTC 473 * 474 * \param chain points to the raw certificate data 475 * \param before valid not before in format YYYY-MM-DD hh:mm:ss 476 * \param after valid not after in format YYYY-MM-DD hh:mm:ss 477 * 478 * \return 0 if successful, or a specific X509 error code 479 */ 480int x509write_add_validity( x509_raw *crt, 481 unsigned char *before, 482 unsigned char *after ); 483 484/** 485 * \brief Create a self-signed certificate 486 * 487 * \param chain points to the raw certificate data 488 * \param rsa a private key to sign the certificate 489 * 490 * \return 0 if successful, or a specific X509 error code 491 */ 492int x509write_create_selfsign( x509_raw *crt, rsa_context *raw ); 493 494/** 495 * \brief Create a certificate 496 * 497 * \param chain points to the raw certificate data 498 * \param rsa a private key to sign the certificate 499 * 500 * \return 0 if successful, or a specific X509 error code 501 */ 502int x509write_create_sign( x509_raw *crt, rsa_context *raw ); 503 504/** 505 * \brief Create a certificate signing request 506 * 507 * \param chain points to the raw certificate data. Didn't use the 508 * same chain that u have use for certificate. 509 * \param privkey a rsa private key 510 * 511 * \return 0 if successful, or a specific X509 error code 512 */ 513int x509write_create_csr( x509_raw *chain, rsa_context *privkey ); 514 515/** 516 * \brief Serialize an rsa key into DER 517 * 518 * \param rsa a rsa key for output 519 * \param node a x509 node for write into 520 * 521 * \return 0 if successful, or a specific X509 error code 522 */ 523int x509write_serialize_key( rsa_context *rsa, x509_node *node ); 524 525/** 526 * \brief Unallocate all raw certificate data 527 */ 528void x509write_free_raw( x509_raw *crt ); 529 530/** 531 * \brief Allocate all raw certificate data 532 */ 533void x509write_init_raw( x509_raw *crt ); 534 535/** 536 * \brief Unallocate all node certificate data 537 */ 538void x509write_free_node( x509_node *crt_node ); 539 540/** 541 * \brief Allocate all node certificate data 542 */ 543void x509write_init_node( x509_node *crt_node ); 544 545#ifdef __cplusplus 546} 547#endif 548 549#endif /* x509.h */ 550