8 #include <openssl/x509v3.h>
9 #include <openssl/pem.h>
12 #include "wvx509mgr.h"
16 static const char * warning_str_get =
"Tried to determine %s, but CRL is blank!\n";
17 #define CHECK_CRL_EXISTS_GET(x, y) \
19 debug(WvLog::Warning, warning_str_get, x); \
29 BN_dec2bn(&bn, serial);
30 ASN1_INTEGER *retval = ASN1_INTEGER_new();
31 retval = BN_to_ASN1_INTEGER(bn, retval);
41 : debug(
"X509 CRL",
WvLog::Debug5)
48 : debug(
"X509 CRL",
WvLog::Debug5)
50 assert(crl = X509_CRL_new());
54 X509_CRL_set_version(crl, 1);
55 X509_CRL_set_issuer_name(crl, X509_get_issuer_name(ca.cert));
58 ASN1_OCTET_STRING *ikeyid = NULL;
60 int i = X509_get_ext_by_NID(ca.cert, NID_subject_key_identifier, -1);
61 if ((i >= 0) && (ext = X509_get_ext(ca.cert, i)))
62 ikeyid =
static_cast<ASN1_OCTET_STRING *
>(X509V3_EXT_d2i(ext));
66 AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new();
67 akeyid->issuer = NULL;
68 akeyid->serial = NULL;
69 akeyid->keyid = ikeyid;
70 ext = X509V3_EXT_i2d(NID_authority_key_identifier, 0, akeyid);
71 X509_CRL_add_ext(crl, ext, -1);
72 X509_EXTENSION_free(ext);
73 AUTHORITY_KEYID_free(akeyid);
97 CHECK_CRL_EXISTS_GET(
"if CRL is signed by CA",
false);
99 EVP_PKEY *pkey = X509_get_pubkey(cacert.cert);
100 int result = X509_CRL_verify(crl, pkey);
104 debug(
"There was an error (%s) determining whether or not we were "
105 "signed by CA '%s'\n", wvssl_errstr(), cacert.
get_subject());
108 bool issigned = (result > 0);
110 debug(
"CRL was%s signed by CA %s\n", issigned ?
"" :
" NOT",
119 CHECK_CRL_EXISTS_GET(
"if CRL is issued by CA",
false);
124 debug(
"CRL issuer '%s' matches subject '%s' of cert. We can say "
125 "that it appears to be issued by this CA.\n",
128 debug(
"CRL issuer '%s' doesn't match subject '%s' of cert. Doesn't "
129 "appear to be issued by this CA.\n", name,
138 CHECK_CRL_EXISTS_GET(
"if CRL has expired",
false);
140 if (X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)) < 0)
142 debug(
"CRL appears to be expired.\n");
146 debug(
"CRL appears not to be expired.\n");
151 bool WvCRL::has_critical_extensions()
const
153 CHECK_CRL_EXISTS_GET(
"if CRL has critical extensions",
false);
155 int critical = X509_CRL_get_ext_by_critical(crl, 1, 0);
156 return (critical > 0);
162 CHECK_CRL_EXISTS_GET(
"CRL's AKI", WvString::null);
164 AUTHORITY_KEYID *aki = NULL;
167 aki =
static_cast<AUTHORITY_KEYID *
>(
168 X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier,
172 char *tmp = hex_to_string(aki->keyid->data, aki->keyid->length);
176 AUTHORITY_KEYID_free(aki);
181 return WvString::null;
187 CHECK_CRL_EXISTS_GET(
"CRL's issuer", WvString::null);
189 char *name = X509_NAME_oneline(X509_CRL_get_issuer(crl), 0, 0);
208 if (mode == CRLFileDER || mode == CRLFilePEM)
213 debug(WvLog::Warning,
"Tried to encode CRL, but CRL is blank!\n");
217 BIO *bufbio = BIO_new(BIO_s_mem());
222 debug(
"Dumping CRL in PEM format.\n");
223 PEM_write_bio_X509_CRL(bufbio, crl);
226 debug(
"Dumping CRL in DER format.\n");
227 i2d_X509_CRL_bio(bufbio, crl);
230 debug(
"Tried to dump CRL in unknown format!\n");
234 BIO_get_mem_ptr(bufbio, &bm);
235 buf.put(bm->data, bm->length);
244 debug(
"Replacing already existant CRL.\n");
249 if (mode == CRLFileDER)
251 BIO *bio = BIO_new(BIO_s_file());
253 if (BIO_read_filename(bio, str.
cstr()) <= 0)
255 debug(WvLog::Warning,
"Import CRL from '%s': %s\n",
256 str, wvssl_errstr());
261 if (!(crl = d2i_X509_CRL_bio(bio, NULL)))
262 debug(WvLog::Warning,
"Read CRL from '%s': %s\n",
263 str, wvssl_errstr());
268 else if (mode == CRLFilePEM)
270 FILE * fp = fopen(str,
"rb");
274 debug(WvLog::Warning,
276 str, strerror(errnum));
280 if (!(crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL)))
281 debug(WvLog::Warning,
"Import CRL from '%s': %s\n",
282 str, wvssl_errstr());
299 debug(
"Replacing already existant CRL.\n");
304 if (mode == CRLFileDER || mode == CRLFilePEM)
310 BIO *bufbio = BIO_new(BIO_s_mem());
311 BIO_write(bufbio, buf.
get(buf.
used()), buf.
used());
315 debug(
"Decoding CRL from PEM format.\n");
316 crl = PEM_read_bio_X509_CRL(bufbio, NULL, NULL, NULL);
318 else if (mode == CRLDER)
320 debug(
"Decoding CRL from DER format.\n");
321 crl = d2i_X509_CRL_bio(bufbio, NULL);
324 debug(WvLog::Warning,
"Attempted to decode unknown format.\n");
327 debug(WvLog::Warning,
"Couldn't decode CRL.\n");
337 debug(
"Checking to see if certificate with name '%s' and serial "
344 debug(WvLog::Error,
"Given certificate to check revocation status, "
345 "but certificate is blank. Declining.\n");
353 CHECK_CRL_EXISTS_GET(
"if certificate is revoked in CRL",
false);
357 ASN1_INTEGER *serial = serial_to_int(serial_number);
360 X509_REVOKED *revoked_entry = NULL;
361 int idx = X509_CRL_get0_by_serial(crl, &revoked_entry, serial);
362 ASN1_INTEGER_free(serial);
363 if (idx >= 1 || revoked_entry)
365 debug(
"Certificate is revoked.\n");
370 debug(
"Certificate is not revoked.\n");
375 debug(WvLog::Warning,
"Can't convert serial number to ASN1 format. "
376 "Saying it's not revoked.\n");
379 debug(WvLog::Warning,
"Serial number for certificate is blank.\n");
381 debug(
"Certificate is not revoked (or could not determine whether it "
393 return NO_VALID_SIGNATURE;
399 if (has_critical_extensions())
401 debug(
"CRL has unhandled critical extensions.\n");
402 return UNHANDLED_CRITICAL_EXTENSIONS;
411 CHECK_CRL_EXISTS_GET(
"number of certificates in CRL", 0);
413 STACK_OF(X509_REVOKED) *rev;
414 rev = X509_CRL_get_REVOKED(crl);
415 int certcount = sk_X509_REVOKED_num(rev);
428 debug(WvLog::Warning,
"Tried to add certificate to CRL, but CRL is "
435 ASN1_INTEGER *serial = serial_to_int(cert.
get_serial());
436 X509_REVOKED *revoked = X509_REVOKED_new();
437 ASN1_GENERALIZEDTIME *now = ASN1_GENERALIZEDTIME_new();
438 X509_REVOKED_set_serialNumber(revoked, serial);
439 X509_gmtime_adj(now, 0);
440 X509_REVOKED_set_revocationDate(revoked, now);
442 X509_CRL_add0_revoked(crl, revoked);
443 ASN1_GENERALIZEDTIME_free(now);
444 ASN1_INTEGER_free(serial);
448 debug(WvLog::Warning,
"Tried to add a certificate to the CRL, but "
449 "certificate is either bad or broken.\n");
bool isok() const
Do we have any errors...
Valid validate(const WvX509 &cacert) const
Checks to see that a CRL is signed and issued by a CA certificate, and that it has not expired...
WvCRL()
Initialize a blank (null) CRL object.
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
Valid
Type for validate() method: ERROR = there was an error that happened.
WvString get_subject() const
get and set the Subject field of the certificate
const char * cstr() const
return a (const char *) for this string.
bool expired() const
Checks to see if the CRL is expired (i.e.
bool issuedbyca(const WvX509 &cacert) const
Check the issuer name of the CRL in crl against the CA certificate in cert.
void addcert(const WvX509 &cert)
Add the certificate specified by cert to the CRL.
X509 Class to handle certificates and their related functions.
WvString encode(const DumpMode mode) const
Return the information requested by mode as a WvString.
virtual ~WvCRL()
Destructor.
WvString get_serial(bool hex=false) const
get and set the serialNumber field of the certificate
WvString get_issuer() const
Get the CRL Issuer.
virtual bool isok() const
Is the certificate object valid?
int numcerts() const
Counts the number of certificates in this CRL.
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers...
void decode(const DumpMode mode, WvStringParm encoded)
Load the information from the format requested by mode into the class - this overwrites the CRL...
size_t used() const
Returns the number of elements in the buffer currently available for reading.
bool signedbyca(const WvX509 &cacert) const
Check the CRL in crl against the CA certificate in cert.
bool isrevoked(const WvX509 &cert) const
Is the certificate in cert revoked?
WvString is an implementation of a simple and efficient printable-string class.
void putstr(WvStringParm str)
Copies a WvString into the buffer, excluding the null-terminator.
const T * get(size_t count)
Reads exactly the specified number of elements and returns a pointer to a storage location owned by t...
A WvLog stream accepts log messages from applications and forwards them to all registered WvLogRcv's...
DumpMode
Type for the encode() and decode() methods: CRLPEM = PEM Encoded X.509 CRL CRLDER = DER Encoded X...
WvString getstr()
Returns the entire buffer as a null-terminated WvString.
WvString get_aki() const
Get the Authority key Info.
bool signcrl(WvCRL &unsignedcrl) const
Sign the CRL with the rsa key associated with this class.