22 #include "../../log.h"
23 #include "../../crypto/OpenSSLHelpers.h"
28 #include <openssl/bio.h>
29 #include <openssl/pem.h>
30 #include <openssl/err.h>
31 #include <openssl/x509v3.h>
47 this->cert = copyX509(cert);
65 const unsigned char* pBytes =
reinterpret_cast<const unsigned char*
>(&bytes[0]);
66 d2i_X509(&cert, &pBytes, (
unsigned int)bytes.size());
69 THROW_IOEXCEPTION(
"Failed to parse X509 certificate from bytes given: %s", ERR_reason_error_string(ERR_get_error()));
82 this->cert = copyX509(copy.cert);
102 this->cert = copyX509(copy.cert);
113 return copyX509(cert);
126 THROW_IOEXCEPTION(
"Failed to copy X509 certificate: %s", ERR_reason_error_string(ERR_get_error()));
127 X509* copy = X509_dup(cert);
129 THROW_IOEXCEPTION(
"Failed to copy X509 certificate: %s", ERR_reason_error_string(ERR_get_error()));
146 BIO*
file = BIO_new_file(path.c_str(),
"rb");
150 path.c_str(), ERR_reason_error_string(ERR_get_error()));
154 X509* cert = PEM_read_bio_X509(file, NULL, NULL, NULL);
159 path.c_str(), ERR_reason_error_string(ERR_get_error()));
174 int bufSize = i2d_X509(cert, NULL);
181 std::vector<unsigned char> derEncodedX509(bufSize, 0);
184 unsigned char* pBuf = &derEncodedX509[0];
185 bufSize = i2d_X509(cert, &pBuf);
191 return derEncodedX509;
200 EVP_PKEY *pubKey = getPublicKey();
201 RSA *rsa = EVP_PKEY_get1_RSA(pubKey);
204 EVP_PKEY_free(pubKey);
205 THROW_IOEXCEPTION(
"Failed to read certificate RSA key: %s", ERR_reason_error_string(ERR_get_error()));
207 int size = RSA_size(rsa);
209 EVP_PKEY_free(pubKey);
220 BIGNUM *bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), 0);
223 char *str = BN_bn2dec(bn);
232 THROW_IOEXCEPTION(
"Failed to read certificate serial number from X.509 certificate: %s", ERR_reason_error_string(ERR_get_error()));
244 return X509_get_issuer_name(cert);
255 X509_NAME* issuerName = X509_get_issuer_name(cert);
257 THROW_IOEXCEPTION(
"Failed to convert X.509 certificate issuer name: %s", ERR_reason_error_string(ERR_get_error()));
259 return toString(issuerName, obj);
269 ASN1_BIT_STRING *keyusage = (ASN1_BIT_STRING*)X509_get_ext_d2i(cert, NID_key_usage, 0, 0);
271 return std::vector<KeyUsage>();
273 std::vector<KeyUsage> usage;
274 for(
int n = 0; n < 9; ++n)
276 if(ASN1_BIT_STRING_get_bit(keyusage, n))
279 ASN1_BIT_STRING_free(keyusage);
290 CERTIFICATEPOLICIES *cp = (CERTIFICATEPOLICIES*)X509_get_ext_d2i(cert, NID_certificate_policies, 0, 0);
292 return std::vector<std::string>();
294 std::vector<std::string> pol;
295 for(
int i = 0;
i < sk_POLICYINFO_num(cp); ++
i)
297 std::string
buf(50, 0);
298 int len = OBJ_obj2txt(&buf[0], buf.size(), sk_POLICYINFO_value(cp,
i)->policyid, 1);
304 sk_POLICYINFO_pop_free(cp, POLICYINFO_free);
316 X509_NAME* subject = X509_get_subject_name(cert);
318 THROW_IOEXCEPTION(
"Failed to convert X.509 certificate subject: %s", ERR_reason_error_string(ERR_get_error()));
320 return toString(subject, obj);
336 for(
int i = 0;
i < X509_NAME_entry_count(name); ++
i)
338 X509_NAME_ENTRY *
e = X509_NAME_get_entry(name,
i);
340 const char *o = OBJ_nid2sn(OBJ_obj2nid(X509_NAME_ENTRY_get_object(e)));
345 int size = ASN1_STRING_to_UTF8((
unsigned char**)&data, X509_NAME_ENTRY_get_data(e));
346 str = std::string(data, size);
353 BIO* mem = BIO_new(BIO_s_mem());
355 THROW_IOEXCEPTION(
"Failed to allocate memory for X509_NAME conversion: %s", ERR_reason_error_string(ERR_get_error()));
358 if(X509_NAME_print_ex(mem, name, 0, XN_FLAG_RFC2253) < 0)
361 THROW_IOEXCEPTION(
"Failed to convert X509_NAME struct to string: %s", ERR_reason_error_string(ERR_get_error()));
367 while((bytesRead = BIO_gets(mem, &buf[0],
sizeof(buf))) > 0)
381 EVP_PKEY* pubKey = X509_get_pubkey(cert);
382 if((pubKey == NULL) || (pubKey->type != EVP_PKEY_RSA))
384 EVP_PKEY_free(pubKey);
385 THROW_IOEXCEPTION(
"Unable to load RSA public Key: %s", ERR_reason_error_string(ERR_get_error()));
396 EVP_PKEY* pubKey = getPublicKey();
399 int bufSize = BN_num_bytes(pubKey->pkey.rsa->n);
403 EVP_PKEY_free(pubKey);
408 std::vector<unsigned char> rsaModulus(bufSize, 0);
411 if(BN_bn2bin(pubKey->pkey.rsa->n, &rsaModulus[0]) <= 0)
413 EVP_PKEY_free(pubKey);
417 EVP_PKEY_free(pubKey);
427 EVP_PKEY* pubKey = getPublicKey();
430 int bufSize = BN_num_bytes(pubKey->pkey.rsa->e);
434 EVP_PKEY_free(pubKey);
439 std::vector<unsigned char> rsaExponent(bufSize, 0);
442 if(BN_bn2bin(pubKey->pkey.rsa->e, &rsaExponent[0]) <= 0)
444 EVP_PKEY_free(pubKey);
448 EVP_PKEY_free(pubKey);
459 int notBefore = X509_cmp_current_time(cert->cert_info->validity->notBefore);
460 int notAfter = X509_cmp_current_time(cert->cert_info->validity->notAfter);
461 if(notBefore == 0 || notAfter == 0)
462 THROW_IOEXCEPTION(
"Failed to validate cert",ERR_reason_error_string(ERR_get_error()));
463 return notBefore < 0 && notAfter > 0;
468 if(cert && other.
cert)
469 return X509_cmp(cert, other.
cert) == 0;
470 if(!cert && !other.
cert)
483 X509_STORE_CTX *csc = X509_STORE_CTX_new();
484 X509_STORE_CTX_scope csct(&csc);
486 THROW_IOEXCEPTION(
"Failed to create X509_STORE_CTX %s",ERR_reason_error_string(ERR_get_error()));
489 X509* x = getX509(); X509_scope xt(&x);
490 if(!X509_STORE_CTX_init(csc, store, x, NULL))
491 THROW_IOEXCEPTION(
"Failed to init X509_STORE_CTX %s",ERR_reason_error_string(ERR_get_error()));
493 int ok = X509_verify_cert(csc);
497 int err = X509_STORE_CTX_get_error(csc);
498 std::ostringstream s;
499 s <<
"Unable to verify ";
500 s <<
". Cause: " << X509_verify_cert_error_string(err);
503 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
505 IOException
e(__FILE__, __LINE__, s.str());
545 size_t pos = 0, old = 0;
548 pos = name.find(
",", old);
549 if(pos == std::string::npos)
557 if(name.compare(pos-1, 1,
"\\") == 0)
561 std::string nameitem = name.substr(old, pos - old);
564 if((pos = nameitem.find(
"=")) == std::string::npos ||
565 nameitem.compare(pos-1, 1,
"\\") == 0)
568 std::string obj = nameitem.substr(0, pos);
569 if(obj.compare(
"CN") != 0 && obj.compare(
"commonName") != 0 &&
570 obj.compare(
"L") != 0 && obj.compare(
"localityName") != 0 &&
571 obj.compare(
"ST") != 0 && obj.compare(
"stateOrProvinceName") != 0 &&
572 obj.compare(
"O") != 0 && obj.compare(
"organizationName") != 0 &&
573 obj.compare(
"OU") != 0 && obj.compare(
"organizationalUnitName") != 0 &&
574 obj.compare(
"C" ) != 0 && obj.compare(
"countryName") != 0 &&
575 obj.compare(
"STREET") != 0 && obj.compare(
"streetAddress") != 0 &&
576 obj.compare(
"DC") != 0 && obj.compare(
"domainComponent") != 0 &&
577 obj.compare(
"UID") != 0 && obj.compare(
"userId") != 0)
580 X509_NAME_ENTRY *enta = X509_NAME_ENTRY_create_by_txt(0, obj.c_str(),
581 MBSTRING_UTF8, (
unsigned char*)nameitem.substr(pos+1, pos-old).c_str(), -1);
585 ASN1_OBJECT *obja = X509_NAME_ENTRY_get_object(enta);
588 for(
int i = 0;
i < X509_NAME_entry_count(getIssuerNameAsn1()); ++
i)
590 X509_NAME_ENTRY *entb = X509_NAME_get_entry(getIssuerNameAsn1(),
i);
591 ASN1_OBJECT *objb = X509_NAME_ENTRY_get_object(entb);
592 if(memcmp(obja->data, objb->data, obja->length) == 0 &&
593 memcmp(enta->value, entb->value, enta->size) == 0)
599 X509_NAME_ENTRY_free(enta);