1189251Ssam/*
2189251Ssam * X.509v3 certificate parsing and processing
3252726Srpaulo * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
4189251Ssam *
5252726Srpaulo * This software may be distributed under the terms of the BSD license.
6252726Srpaulo * See README for more details.
7189251Ssam */
8189251Ssam
9189251Ssam#ifndef X509V3_H
10189251Ssam#define X509V3_H
11189251Ssam
12189251Ssam#include "asn1.h"
13189251Ssam
14189251Ssamstruct x509_algorithm_identifier {
15189251Ssam	struct asn1_oid oid;
16189251Ssam};
17189251Ssam
18214734Srpaulostruct x509_name_attr {
19214734Srpaulo	enum x509_name_attr_type {
20214734Srpaulo		X509_NAME_ATTR_NOT_USED,
21214734Srpaulo		X509_NAME_ATTR_DC,
22214734Srpaulo		X509_NAME_ATTR_CN,
23214734Srpaulo		X509_NAME_ATTR_C,
24214734Srpaulo		X509_NAME_ATTR_L,
25214734Srpaulo		X509_NAME_ATTR_ST,
26214734Srpaulo		X509_NAME_ATTR_O,
27214734Srpaulo		X509_NAME_ATTR_OU
28214734Srpaulo	} type;
29214734Srpaulo	char *value;
30214734Srpaulo};
31214734Srpaulo
32214734Srpaulo#define X509_MAX_NAME_ATTRIBUTES 20
33214734Srpaulo
34189251Ssamstruct x509_name {
35214734Srpaulo	struct x509_name_attr attr[X509_MAX_NAME_ATTRIBUTES];
36214734Srpaulo	size_t num_attr;
37189251Ssam	char *email; /* emailAddress */
38214734Srpaulo
39214734Srpaulo	/* from alternative name extension */
40214734Srpaulo	char *alt_email; /* rfc822Name */
41214734Srpaulo	char *dns; /* dNSName */
42214734Srpaulo	char *uri; /* uniformResourceIdentifier */
43214734Srpaulo	u8 *ip; /* iPAddress */
44214734Srpaulo	size_t ip_len; /* IPv4: 4, IPv6: 16 */
45214734Srpaulo	struct asn1_oid rid; /* registeredID */
46189251Ssam};
47189251Ssam
48189251Ssamstruct x509_certificate {
49189251Ssam	struct x509_certificate *next;
50189251Ssam	enum { X509_CERT_V1 = 0, X509_CERT_V2 = 1, X509_CERT_V3 = 2 } version;
51189251Ssam	unsigned long serial_number;
52189251Ssam	struct x509_algorithm_identifier signature;
53189251Ssam	struct x509_name issuer;
54189251Ssam	struct x509_name subject;
55189251Ssam	os_time_t not_before;
56189251Ssam	os_time_t not_after;
57189251Ssam	struct x509_algorithm_identifier public_key_alg;
58189251Ssam	u8 *public_key;
59189251Ssam	size_t public_key_len;
60189251Ssam	struct x509_algorithm_identifier signature_alg;
61189251Ssam	u8 *sign_value;
62189251Ssam	size_t sign_value_len;
63189251Ssam
64189251Ssam	/* Extensions */
65189251Ssam	unsigned int extensions_present;
66189251Ssam#define X509_EXT_BASIC_CONSTRAINTS		(1 << 0)
67189251Ssam#define X509_EXT_PATH_LEN_CONSTRAINT		(1 << 1)
68189251Ssam#define X509_EXT_KEY_USAGE			(1 << 2)
69214734Srpaulo#define X509_EXT_SUBJECT_ALT_NAME		(1 << 3)
70214734Srpaulo#define X509_EXT_ISSUER_ALT_NAME		(1 << 4)
71189251Ssam
72189251Ssam	/* BasicConstraints */
73189251Ssam	int ca; /* cA */
74189251Ssam	unsigned long path_len_constraint; /* pathLenConstraint */
75189251Ssam
76189251Ssam	/* KeyUsage */
77189251Ssam	unsigned long key_usage;
78189251Ssam#define X509_KEY_USAGE_DIGITAL_SIGNATURE	(1 << 0)
79189251Ssam#define X509_KEY_USAGE_NON_REPUDIATION		(1 << 1)
80189251Ssam#define X509_KEY_USAGE_KEY_ENCIPHERMENT		(1 << 2)
81189251Ssam#define X509_KEY_USAGE_DATA_ENCIPHERMENT	(1 << 3)
82189251Ssam#define X509_KEY_USAGE_KEY_AGREEMENT		(1 << 4)
83189251Ssam#define X509_KEY_USAGE_KEY_CERT_SIGN		(1 << 5)
84189251Ssam#define X509_KEY_USAGE_CRL_SIGN			(1 << 6)
85189251Ssam#define X509_KEY_USAGE_ENCIPHER_ONLY		(1 << 7)
86189251Ssam#define X509_KEY_USAGE_DECIPHER_ONLY		(1 << 8)
87189251Ssam
88189251Ssam	/*
89189251Ssam	 * The DER format certificate follows struct x509_certificate. These
90189251Ssam	 * pointers point to that buffer.
91189251Ssam	 */
92189251Ssam	const u8 *cert_start;
93189251Ssam	size_t cert_len;
94189251Ssam	const u8 *tbs_cert_start;
95189251Ssam	size_t tbs_cert_len;
96189251Ssam};
97189251Ssam
98189251Ssamenum {
99189251Ssam	X509_VALIDATE_OK,
100189251Ssam	X509_VALIDATE_BAD_CERTIFICATE,
101189251Ssam	X509_VALIDATE_UNSUPPORTED_CERTIFICATE,
102189251Ssam	X509_VALIDATE_CERTIFICATE_REVOKED,
103189251Ssam	X509_VALIDATE_CERTIFICATE_EXPIRED,
104189251Ssam	X509_VALIDATE_CERTIFICATE_UNKNOWN,
105189251Ssam	X509_VALIDATE_UNKNOWN_CA
106189251Ssam};
107189251Ssam
108189251Ssamvoid x509_certificate_free(struct x509_certificate *cert);
109189251Ssamstruct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len);
110189251Ssamvoid x509_name_string(struct x509_name *name, char *buf, size_t len);
111189251Ssamint x509_name_compare(struct x509_name *a, struct x509_name *b);
112189251Ssamvoid x509_certificate_chain_free(struct x509_certificate *cert);
113189251Ssamint x509_certificate_check_signature(struct x509_certificate *issuer,
114189251Ssam				     struct x509_certificate *cert);
115189251Ssamint x509_certificate_chain_validate(struct x509_certificate *trusted,
116189251Ssam				    struct x509_certificate *chain,
117252726Srpaulo				    int *reason, int disable_time_checks);
118189251Ssamstruct x509_certificate *
119189251Ssamx509_certificate_get_subject(struct x509_certificate *chain,
120189251Ssam			     struct x509_name *name);
121189251Ssamint x509_certificate_self_signed(struct x509_certificate *cert);
122189251Ssam
123189251Ssam#endif /* X509V3_H */
124