18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * X.509v3 certificate parsing and processing
3c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef X509V3_H
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509V3_H
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "asn1.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct x509_algorithm_identifier {
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct asn1_oid oid;
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct x509_name_attr {
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum x509_name_attr_type {
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		X509_NAME_ATTR_NOT_USED,
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		X509_NAME_ATTR_DC,
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		X509_NAME_ATTR_CN,
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		X509_NAME_ATTR_C,
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		X509_NAME_ATTR_L,
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		X509_NAME_ATTR_ST,
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		X509_NAME_ATTR_O,
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		X509_NAME_ATTR_OU
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} type;
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *value;
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_MAX_NAME_ATTRIBUTES 20
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct x509_name {
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct x509_name_attr attr[X509_MAX_NAME_ATTRIBUTES];
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t num_attr;
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *email; /* emailAddress */
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* from alternative name extension */
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *alt_email; /* rfc822Name */
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *dns; /* dNSName */
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *uri; /* uniformResourceIdentifier */
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *ip; /* iPAddress */
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t ip_len; /* IPv4: 4, IPv6: 16 */
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct asn1_oid rid; /* registeredID */
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct x509_certificate {
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct x509_certificate *next;
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum { X509_CERT_V1 = 0, X509_CERT_V2 = 1, X509_CERT_V3 = 2 } version;
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned long serial_number;
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct x509_algorithm_identifier signature;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct x509_name issuer;
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct x509_name subject;
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_time_t not_before;
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_time_t not_after;
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct x509_algorithm_identifier public_key_alg;
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *public_key;
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t public_key_len;
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct x509_algorithm_identifier signature_alg;
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *sign_value;
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t sign_value_len;
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Extensions */
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int extensions_present;
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_EXT_BASIC_CONSTRAINTS		(1 << 0)
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_EXT_PATH_LEN_CONSTRAINT		(1 << 1)
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_EXT_KEY_USAGE			(1 << 2)
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_EXT_SUBJECT_ALT_NAME		(1 << 3)
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_EXT_ISSUER_ALT_NAME		(1 << 4)
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* BasicConstraints */
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ca; /* cA */
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned long path_len_constraint; /* pathLenConstraint */
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* KeyUsage */
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned long key_usage;
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_KEY_USAGE_DIGITAL_SIGNATURE	(1 << 0)
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_KEY_USAGE_NON_REPUDIATION		(1 << 1)
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_KEY_USAGE_KEY_ENCIPHERMENT		(1 << 2)
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_KEY_USAGE_DATA_ENCIPHERMENT	(1 << 3)
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_KEY_USAGE_KEY_AGREEMENT		(1 << 4)
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_KEY_USAGE_KEY_CERT_SIGN		(1 << 5)
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_KEY_USAGE_CRL_SIGN			(1 << 6)
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_KEY_USAGE_ENCIPHER_ONLY		(1 << 7)
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define X509_KEY_USAGE_DECIPHER_ONLY		(1 << 8)
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * The DER format certificate follows struct x509_certificate. These
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * pointers point to that buffer.
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *cert_start;
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t cert_len;
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *tbs_cert_start;
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t tbs_cert_len;
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtenum {
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	X509_VALIDATE_OK,
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	X509_VALIDATE_BAD_CERTIFICATE,
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	X509_VALIDATE_UNSUPPORTED_CERTIFICATE,
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	X509_VALIDATE_CERTIFICATE_REVOKED,
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	X509_VALIDATE_CERTIFICATE_EXPIRED,
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	X509_VALIDATE_CERTIFICATE_UNKNOWN,
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	X509_VALIDATE_UNKNOWN_CA
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid x509_certificate_free(struct x509_certificate *cert);
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len);
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid x509_name_string(struct x509_name *name, char *buf, size_t len);
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint x509_name_compare(struct x509_name *a, struct x509_name *b);
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid x509_certificate_chain_free(struct x509_certificate *cert);
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint x509_certificate_check_signature(struct x509_certificate *issuer,
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     struct x509_certificate *cert);
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint x509_certificate_chain_validate(struct x509_certificate *trusted,
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    struct x509_certificate *chain,
117c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt				    int *reason, int disable_time_checks);
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct x509_certificate *
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtx509_certificate_get_subject(struct x509_certificate *chain,
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     struct x509_name *name);
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint x509_certificate_self_signed(struct x509_certificate *cert);
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* X509V3_H */
124