summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe/ocsp.h
blob: be0bddc50e100d30402e4fd447883c1a85ffb42f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#ifndef _IPXE_OCSP_H
#define _IPXE_OCSP_H

/** @file
 *
 * Online Certificate Status Protocol
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdarg.h>
#include <time.h>
#include <ipxe/asn1.h>
#include <ipxe/x509.h>
#include <ipxe/refcnt.h>
#include <config/crypto.h>

/* Allow OCSP to be disabled completely */
#ifdef OCSP_CHECK
#define OCSP_ENABLED 1
#else
#define OCSP_ENABLED 0
#endif

/** OCSP algorithm identifier */
#define OCSP_ALGORITHM_IDENTIFIER( ... )				\
	ASN1_OID, VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__,		\
	ASN1_NULL, 0x00

/* OCSP response statuses */
#define OCSP_STATUS_SUCCESSFUL		0x00
#define OCSP_STATUS_MALFORMED_REQUEST	0x01
#define OCSP_STATUS_INTERNAL_ERROR	0x02
#define OCSP_STATUS_TRY_LATER		0x03
#define OCSP_STATUS_SIG_REQUIRED	0x05
#define OCSP_STATUS_UNAUTHORIZED	0x06

struct ocsp_check;

/** An OCSP request */
struct ocsp_request {
	/** Request builder */
	struct asn1_builder builder;
	/** Certificate ID */
	struct asn1_cursor cert_id;
};

/** An OCSP responder */
struct ocsp_responder {
	/**
	 * Check if certificate is the responder's certificate
	 *
	 * @v ocsp		OCSP check
	 * @v cert		Certificate
	 * @ret difference	Difference as returned by memcmp()
	 */
	int ( * compare ) ( struct ocsp_check *ocsp,
			    struct x509_certificate *cert );
	/** Responder ID */
	struct asn1_cursor id;
};

/** An OCSP response */
struct ocsp_response {
	/** Raw response */
	void *data;
	/** Raw tbsResponseData */
	struct asn1_cursor tbs;
	/** Responder */
	struct ocsp_responder responder;
	/** Time at which status is known to be correct */
	time_t this_update;
	/** Time at which newer status information will be available */
	time_t next_update;
	/** Signature algorithm */
	struct asn1_algorithm *algorithm;
	/** Signature value */
	struct asn1_bit_string signature;
	/** Signing certificate */
	struct x509_certificate *signer;
};

/** An OCSP check */
struct ocsp_check {
	/** Reference count */
	struct refcnt refcnt;
	/** Certificate being checked */
	struct x509_certificate *cert;
	/** Issuing certificate */
	struct x509_certificate *issuer;
	/** URI string */
	char *uri_string;
	/** Request */
	struct ocsp_request request;
	/** Response */
	struct ocsp_response response;
};

/**
 * Get reference to OCSP check
 *
 * @v ocsp		OCSP check
 * @ret ocsp		OCSP check
 */
static inline __attribute__ (( always_inline )) struct ocsp_check *
ocsp_get ( struct ocsp_check *ocsp ) {
	ref_get ( &ocsp->refcnt );
	return ocsp;
}

/**
 * Drop reference to OCSP check
 *
 * @v ocsp		OCSP check
 */
static inline __attribute__ (( always_inline )) void
ocsp_put ( struct ocsp_check *ocsp ) {
	ref_put ( &ocsp->refcnt );
}

/**
 * Check if X.509 certificate requires an OCSP check
 *
 * @v cert		X.509 certificate
 * @ret ocsp_required	An OCSP check is required
 */
static inline int ocsp_required ( struct x509_certificate *cert ) {

	/* An OCSP check is never required if OCSP checks are disabled */
	if ( ! OCSP_ENABLED )
		return 0;

	/* An OCSP check is required if an OCSP URI exists but the
	 * OCSP status is not (yet) good.
	 */
	return ( cert->extensions.auth_info.ocsp.uri.len &&
		 ( ! cert->extensions.auth_info.ocsp.good ) );
}

extern int ocsp_check ( struct x509_certificate *cert,
			struct x509_certificate *issuer,
			struct ocsp_check **ocsp );
extern int ocsp_response ( struct ocsp_check *ocsp, const void *data,
			   size_t len );
extern int ocsp_validate ( struct ocsp_check *check, time_t time );

#endif /* _IPXE_OCSP_H */