4 * @brief Implementation of certificate_t.
9 * Copyright (C) 2006 Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 #include "certificate.h"
30 #include <asn1/der_decoder.h>
33 typedef struct private_certificate_t private_certificate_t
;
36 * Private data of a certificate_t object.
38 struct private_certificate_t
{
40 * Public interface for this signer.
67 rsa_public_key_t
*public_key
;
70 #define OSET(x) offsetof(private_certificate_t, x)
73 * Rules for de-/encoding of a certificate from/in ASN1
75 static asn1_rule_t certificate_rules
[] = {
76 {ASN1_SEQUENCE
, 0, 0, 0 }, /* certificate */
77 { ASN1_SEQUENCE
, ASN1_RAW
, OSET(tbs_cert
), 0 }, /* tbsCertificate */
78 { ASN1_TAG_E_0
, ASN1_DEFAULT
, OSET(version
), 0 }, /* EXPLICIT */
79 { ASN1_INTEGER
, ASN1_DEFAULT
, OSET(version
), 0 }, /* version DEFAULT v1(0) */
80 { ASN1_INTEGER
, 0, OSET(serial
), 0 }, /* serialNumber */
81 { ASN1_SEQUENCE
, 0, 0, 0 }, /* signature */
82 { ASN1_OID
, 0, OSET(sign_alg
), 0 }, /* algorithm-oid */
83 { ASN1_NULL
, 0, 0, 0 }, /* parameters */
84 { ASN1_END
, 0, 0, 0 }, /* signature */
85 { ASN1_SEQUENCE
, ASN1_OF
, 0, 0 }, /* issuer */
86 // { ASN1_SET, ASN1_OF, 0, 0, }, /* RelativeDistinguishedName */
87 // { ASN1_SEQUENCE, 0, 0, 0, }, /* AttributeTypeAndValue */
88 // { ASN1_OID, 0, 0, 0 }, /* AttributeType */
89 // { ASN1_ANY, 0, 0, 0 }, /* AttributeValue */
90 // { ASN1_END, 0, 0, 0 }, /* AttributeTypeAndValue */
91 // { ASN1_END, 0, 0, 0 }, /* RelativeDistinguishedName */
92 { ASN1_END
, 0, 0, 0 }, /* issuer */
93 { ASN1_SEQUENCE
, 0, 0, 0 }, /* validity */
94 { ASN1_CHOICE
, 0, 0, 0 }, /* notBefore */
95 { ASN1_UTCTIME
, 0, OSET(not_before
), 0 }, /* utcTime */
96 { ASN1_GENERALIZEDTIME
, 0, OSET(not_before
), 0 }, /* generalTime */
97 { ASN1_END
, 0, 0, 0 }, /* notBefore */
98 { ASN1_CHOICE
, 0, 0, 0 }, /* notAfter */
99 { ASN1_UTCTIME
, 0, OSET(not_after
), 0 }, /* utcTime */
100 { ASN1_GENERALIZEDTIME
, 0, OSET(not_after
), 0 }, /* generalTime */
101 { ASN1_END
, 0, 0, 0 }, /* notAfter */
102 { ASN1_END
, 0, 0, 0 }, /* validity */
103 { ASN1_SEQUENCE
, ASN1_OF
, 0, 0 }, /* subject */
104 // { ASN1_SET, ASN1_OF, 0, 0, }, /* RelativeDistinguishedName */
105 // { ASN1_SEQUENCE, 0, 0, 0, }, /* AttributeTypeAndValue */
106 // { ASN1_OID, 0, 0, 0 }, /* AttributeType */
107 // { ASN1_ANY, 0, 0, 0 }, /* AttributeValue */
108 // { ASN1_END, 0, 0, 0 }, /* AttributeTypeAndValue */
109 // { ASN1_END, 0, 0, 0 }, /* RelativeDistinguishedName */
110 { ASN1_END
, 0, 0, 0 }, /* subject */
111 { ASN1_SEQUENCE
, 0, 0, 0 }, /* subjectPublicKeyInfo */
112 { ASN1_SEQUENCE
, 0, 0, 0 }, /* algorithm */
113 { ASN1_OID
, 0, OSET(pubkey_alg
), 0 }, /* algorithm-oid */
114 { ASN1_NULL
, 0, 0, 0 }, /* parameters */
115 { ASN1_END
, 0, 0, 0 }, /* algorithm */
116 { ASN1_BITSTRING
, 0, OSET(pubkey
), 0 }, /* subjectPublicKey */
117 { ASN1_END
, 0, 0, 0 }, /* subjectPublicKeyInfo */
118 { ASN1_TAG_I_1
, ASN1_OPTIONAL
, 0, OSET(has_issuer_uid
)}, /* IMPLICIT */
119 { ASN1_BITSTRING
, ASN1_OPTIONAL
, OSET(issuer_uid
), 0 }, /* issuerUniqueID OPTIONAL */
120 { ASN1_TAG_I_2
, ASN1_OPTIONAL
, 0, OSET(has_subject_uid
)},/* IMPLICIT */
121 { ASN1_BITSTRING
, ASN1_OPTIONAL
, OSET(subject_uid
), 0 }, /* subjectUniqueID OPTIONAL */
122 { ASN1_TAG_E_3
, ASN1_OPTIONAL
, 0, 0 }, /* EXPLICIT */
123 { ASN1_SEQUENCE
, ASN1_OF
|ASN1_OPTIONAL
, 0, 0 }, /* extensions OPTIONAL */
124 // { ASN1_SEQUENCE, 0, 0, 0, }, /* extension */
125 // { ASN1_OID, 0, 0, 0 }, /* extnID */
126 // { ASN1_BOOLEAN, ASN1_DEFAULT, 0, FALSE }, /* critical */
127 // { ASN1_OCTETSTRING, 0, 0, 0, }, /* extnValue */
128 // { ASN1_END, 0, 0, 0, }, /* extension */
129 { ASN1_END
, 0, 0, 0, }, /* extensions */
130 { ASN1_END
, 0, 0, 0 }, /* tbsCertificate */
131 { ASN1_SEQUENCE
, 0, 0, 0 }, /* signatureAlgorithm */
132 { ASN1_OID
, 0, OSET(sign_alg
), 0 }, /* algorithm-oid */
133 { ASN1_NULL
, 0, 0, 0 }, /* parameters */
134 { ASN1_END
, 0, 0, 0 }, /* signatureAlgorithm */
135 { ASN1_BITSTRING
, 0, OSET(signature
), 0 }, /* signatureValue */
136 {ASN1_END
, 0, 0, 0 }, /* certificate */
140 * Implementation of certificate.get_public_key.
142 static rsa_public_key_t
*get_public_key(private_certificate_t
*this)
144 return this->public_key
->clone(this->public_key
);
148 * Implementation of certificate.destroy.
150 static void destroy(private_certificate_t
*this)
152 this->public_key
->destroy(this->public_key
);
153 free(this->pubkey
.ptr
);
154 free(this->signature
.ptr
);
155 free(this->tbs_cert
.ptr
);
160 * Described in header.
162 certificate_t
*certificate_create_from_chunk(chunk_t chunk
)
164 private_certificate_t
*this = malloc_thing(private_certificate_t
);
167 /* public functions */
168 this->public.get_public_key
= (rsa_public_key_t
*(*) (certificate_t
*))get_public_key
;
169 this->public.destroy
= (void (*) (certificate_t
*))destroy
;
172 this->pubkey
= CHUNK_INITIALIZER
;
173 this->signature
= CHUNK_INITIALIZER
;
174 this->tbs_cert
= CHUNK_INITIALIZER
;
176 dd
= der_decoder_create(certificate_rules
);
178 if (dd
->decode(dd
, chunk
, this) != SUCCESS
)
186 this->public_key
= rsa_public_key_create_from_chunk(this->pubkey
);
187 if (this->public_key
== NULL
)
189 free(this->pubkey
.ptr
);
194 return &this->public;
198 * Described in header.
200 certificate_t
*certificate_create_from_file(char *filename
)
207 if (stat(filename
, &stb
) == -1)
212 buffer
= alloca(stb
.st_size
);
214 file
= fopen(filename
, "r");
220 if (fread(buffer
, stb
.st_size
, 1, file
) == -1)
228 chunk
.len
= stb
.st_size
;
230 return certificate_create_from_chunk(chunk
);