bool Server::isKeyForCert(const QSslKey &key, const QSslCertificate &cert) { if (key.isNull() || cert.isNull() || (key.type() != QSsl::PrivateKey)) return false; QByteArray qbaKey = key.toDer(); QByteArray qbaCert = cert.toDer(); X509 *x509 = NULL; EVP_PKEY *pkey = NULL; BIO *mem = NULL; mem = BIO_new_mem_buf(qbaKey.data(), qbaKey.size()); Q_UNUSED(BIO_set_close(mem, BIO_NOCLOSE)); pkey = d2i_PrivateKey_bio(mem, NULL); BIO_free(mem); mem = BIO_new_mem_buf(qbaCert.data(), qbaCert.size()); Q_UNUSED(BIO_set_close(mem, BIO_NOCLOSE)); x509 = d2i_X509_bio(mem, NULL); BIO_free(mem); mem = NULL; if (x509 && pkey && X509_check_private_key(x509, pkey)) { EVP_PKEY_free(pkey); X509_free(x509); return true; } if (pkey) EVP_PKEY_free(pkey); if (x509) X509_free(x509); return false; }
int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) { int ret = 0; BIO *in = NULL; int i, count = 0; X509 *x = NULL; if (file == NULL) return (1); in = BIO_new(BIO_s_file_internal()); if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB); goto err; } if (type == X509_FILETYPE_PEM) { for (;;) { x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); if (x == NULL) { if ((ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) && (count > 0)) { ERR_clear_error(); break; } else { X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB); goto err; } } i = X509_STORE_add_cert(ctx->store_ctx, x); if (!i) goto err; count++; X509_free(x); x = NULL; } ret = count; } else if (type == X509_FILETYPE_ASN1) { x = d2i_X509_bio(in, NULL); if (x == NULL) { X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB); goto err; } i = X509_STORE_add_cert(ctx->store_ctx, x); if (!i) goto err; ret = i; } else { X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); goto err; } err: if (x != NULL) X509_free(x); if (in != NULL) BIO_free(in); return (ret); }
/* validate the certifcate stored in 'data' by querying the ocsp-responder */ int ocsp_validate_cert(struct iked *env, struct iked_static_id *id, void *data, size_t len, struct iked_sahdr sh, uint8_t type) { struct iked_ocsp_entry *ioe; struct iked_ocsp *ocsp; BIO *rawcert = NULL, *bissuer = NULL; X509 *cert = NULL, *issuer = NULL; if ((ioe = calloc(1, sizeof(*ioe))) == NULL) return (-1); if ((ocsp = calloc(1, sizeof(*ocsp))) == NULL) { free(ioe); return (-1); } ocsp->ocsp_env = env; ocsp->ocsp_sh = sh; ocsp->ocsp_type = type; if ((rawcert = BIO_new_mem_buf(data, len)) == NULL || (cert = d2i_X509_bio(rawcert, NULL)) == NULL || (bissuer = BIO_new_file(IKED_OCSP_ISSUER, "r")) == NULL || (issuer = PEM_read_bio_X509(bissuer, NULL, NULL, NULL)) == NULL || (ocsp->ocsp_cbio = BIO_new(BIO_s_socket())) == NULL || (ocsp->ocsp_req = OCSP_REQUEST_new()) == NULL || !(ocsp->ocsp_id = OCSP_cert_to_id(NULL, cert, issuer)) || !OCSP_request_add0_id(ocsp->ocsp_req, ocsp->ocsp_id)) goto err; BIO_free(rawcert); BIO_free(bissuer); X509_free(cert); X509_free(issuer); ioe->ioe_ocsp = ocsp; TAILQ_INSERT_TAIL(&env->sc_ocsp, ioe, ioe_entry); /* request connection to ocsp-responder */ proc_compose_imsg(&env->sc_ps, PROC_PARENT, -1, IMSG_OCSP_FD, -1, NULL, 0); return (0); err: ca_sslerror(__func__); free(ioe); if (rawcert != NULL) BIO_free(rawcert); if (cert != NULL) X509_free(cert); if (bissuer != NULL) BIO_free(bissuer); if (issuer != NULL) X509_free(issuer); ocsp_validate_finish(ocsp, 0); /* failed */ return (-1); }
X509 *SSL_read_X509(FILE *fp, X509 **x509, int (*cb)(char *, int, int, void*)) #endif { X509 *rc; BIO *bioS; BIO *bioF; /* 1. try PEM (= DER+Base64+headers) */ #if SSL_LIBRARY_VERSION < 0x00904000 rc = PEM_read_X509(fp, x509, cb); #else rc = PEM_read_X509(fp, x509, cb, NULL); #endif if (rc == NULL) { /* 2. try DER+Base64 */ fseek(fp, 0L, SEEK_SET); if ((bioS = BIO_new(BIO_s_fd())) == NULL) return NULL; BIO_set_fd(bioS, fileno(fp), BIO_NOCLOSE); if ((bioF = BIO_new(BIO_f_base64())) == NULL) { BIO_free(bioS); return NULL; } bioS = BIO_push(bioF, bioS); rc = d2i_X509_bio(bioS, NULL); BIO_free_all(bioS); if (rc == NULL) { /* 3. try plain DER */ fseek(fp, 0L, SEEK_SET); if ((bioS = BIO_new(BIO_s_fd())) == NULL) return NULL; BIO_set_fd(bioS, fileno(fp), BIO_NOCLOSE); rc = d2i_X509_bio(bioS, NULL); BIO_free(bioS); } } if (rc != NULL && x509 != NULL) { if (*x509 != NULL) X509_free(*x509); *x509 = rc; } return rc; }
int main(int argc, char **argv) { X509 *x509 = NULL; BIO *bio = NULL; has_t *crt = NULL; char *json = NULL; size_t l; openssl_init(); if ((bio = BIO_new(BIO_s_file())) == NULL) { return -1; } if(argc < 2) { BIO_set_fp(bio, stdin, BIO_NOCLOSE); } else { BIO_read_filename(bio, argv[1]); } /* Format DER */ if((x509 = d2i_X509_bio(bio, NULL)) == NULL) { ERR_clear_error(); BIO_reset(bio); /* Format PEM */ x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL); } if(!x509) { fprintf(stderr, "Error loading certificate\n"); return -1; } if((crt = has_x509_new(x509)) == NULL) { fprintf(stderr, "Error converting certificate\n"); return -1; } if(has_json_serialize(crt, &json, &l, HAS_JSON_SERIALIZE_PRETTY) == 0) { printf("%s\n", json); free(json); } else { fprintf(stderr, "Error serializing certificate\n"); return -1; } has_free(crt); X509_free(x509); BIO_free(bio); openssl_cleanup(); return 0; }
X509 *SSL_read_X509(char* filename, X509 **x509, pem_password_cb *cb) { X509 *rc; BIO *bioS; BIO *bioF; /* 1. try PEM (= DER+Base64+headers) */ if ((bioS=BIO_new_file(filename, "r")) == NULL) return NULL; rc = PEM_read_bio_X509 (bioS, x509, cb, NULL); BIO_free(bioS); if (rc == NULL) { /* 2. try DER+Base64 */ if ((bioS=BIO_new_file(filename, "r")) == NULL) return NULL; if ((bioF = BIO_new(BIO_f_base64())) == NULL) { BIO_free(bioS); return NULL; } bioS = BIO_push(bioF, bioS); rc = d2i_X509_bio(bioS, NULL); BIO_free_all(bioS); if (rc == NULL) { /* 3. try plain DER */ if ((bioS=BIO_new_file(filename, "r")) == NULL) return NULL; rc = d2i_X509_bio(bioS, NULL); BIO_free(bioS); } } if (rc != NULL && x509 != NULL) { if (*x509 != NULL) X509_free(*x509); *x509 = rc; } return rc; }
int SSL_use_certificate_file (SSL * ssl, const char *file, int type) { int j; BIO *in; int ret = 0; X509 *x = NULL; in = BIO_new (BIO_s_file_internal ()); if (in == NULL) { SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename (in, file) <= 0) { SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; x = d2i_X509_bio (in, NULL); } else if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; x = PEM_read_bio_X509 (in, NULL, ssl->ctx->default_passwd_callback, ssl->ctx->default_passwd_callback_userdata); } else { SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); goto end; } if (x == NULL) { SSLerr (SSL_F_SSL_USE_CERTIFICATE_FILE, j); goto end; } ret = SSL_use_certificate (ssl, x); end: if (x != NULL) X509_free (x); if (in != NULL) BIO_free (in); return (ret); }
/* * Convert bytea to X509. */ static X509 * x509_from_bytea(const bytea *raw) { BIO *bio; X509 *cert; // convert into X509 bio = BIO_new_mem_buf(VARDATA(raw), VARSIZE(raw) - VARHDRSZ); BIO_set_close(bio, BIO_NOCLOSE); cert = X509_new(); d2i_X509_bio(bio, &cert); BIO_free(bio); return cert; }
/*convert CERTCertificate to X509*/ static X509* X509_from_CERTCertificate(const CERTCertificate *cert) { X509 *x509 = NULL; BIO *mbio; mbio = BIO_new_mem_buf(cert->derCert.data, cert->derCert.len); if (mbio == NULL) return(NULL); x509 = d2i_X509_bio(mbio, NULL); BIO_free(mbio); return(x509); }
SigVerifyResult verify_signature(const char *path, const char *sig_path) { for (const std::string &hex_der : valid_certs) { std::string der; if (!hex2bin(hex_der, der)) { LOGE("Failed to convert hex-encoded certificate to binary: %s", hex_der.c_str()); return SigVerifyResult::Failure; } // Cast to (void *) is okay since BIO_new_mem_buf() creates a read-only // BIO object ScopedBIO bio_x509_cert(BIO_new_mem_buf( der.data(), static_cast<int>(der.size())), BIO_free); if (!bio_x509_cert) { LOGE("Failed to create BIO for X509 certificate: %s", hex_der.c_str()); openssl_log_errors(); return SigVerifyResult::Failure; } // Load DER-encoded certificate ScopedX509 cert(d2i_X509_bio(bio_x509_cert.get(), nullptr), X509_free); if (!cert) { LOGE("Failed to load X509 certificate: %s", hex_der.c_str()); openssl_log_errors(); return SigVerifyResult::Failure; } // Get public key from certificate ScopedEVP_PKEY public_key(X509_get_pubkey(cert.get()), EVP_PKEY_free); if (!public_key) { LOGE("Failed to load public key from X509 certificate: %s", hex_der.c_str()); openssl_log_errors(); return SigVerifyResult::Failure; } SigVerifyResult result = verify_signature_with_key(path, sig_path, *public_key); if (result == SigVerifyResult::Invalid) { // Keep trying ... continue; } return result; } return SigVerifyResult::Invalid; }
swSSLCertificate *swSSLCertificateNewFromDER(swStaticBuffer *buffer) { swSSLCertificate *cert = NULL; if (buffer) { BIO *pemBIO = BIO_new_mem_buf(buffer->data, buffer->len); if (pemBIO) { cert = d2i_X509_bio(pemBIO, NULL); BIO_free_all(pemBIO); } } return cert; }
bool SslCertificate::Load(const String& data, bool asn1) { Clear(); SslStream in, pem, *sio = ∈ if(!in.OpenBuffer(data, data.GetLength())) return false; if(!asn1) { if(!pem.Create(BIO_f_base64())) return false; BIO_push(pem, in); sio = &pem; } return Set(d2i_X509_bio(*sio, NULL)); }
/* * We will put into store X509 object from passed data in buffer only * when object name match passed. To compare both names we use our * method "ssh_X509_NAME_cmp"(it is more general). */ static int/*bool*/ ldaplookup_data2store( int type, X509_NAME* name, void* buf, int len, X509_STORE* store ) { int ok = 0; BIO *mbio; if (name == NULL) return(0); if (buf == NULL) return(0); if (len <= 0) return(0); if (store == NULL) return(0); mbio = BIO_new_mem_buf(buf, len); if (mbio == NULL) return(0); switch (type) { case X509_LU_X509: { X509 *x509 = d2i_X509_bio(mbio, NULL); if(x509 == NULL) goto exit; /*This is correct since lookup method is by subject*/ if (ssh_X509_NAME_cmp(name, X509_get_subject_name(x509)) != 0) goto exit; ok = X509_STORE_add_cert(store, x509); } break; case X509_LU_CRL: { X509_CRL *crl = d2i_X509_CRL_bio(mbio, NULL); if(crl == NULL) goto exit; if (ssh_X509_NAME_cmp(name, X509_CRL_get_issuer(crl)) != 0) goto exit; ok = X509_STORE_add_crl(store, crl); } break; } exit: if (mbio != NULL) BIO_free_all(mbio); #ifdef TRACE_BY_LDAP fprintf(stderr, "TRACE_BY_LDAP ldaplookup_data2store: ok=%d\n", ok); #endif return(ok); }
int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { int reason_code; BIO *in; int ret = 0; X509 *x = NULL; in = BIO_new(BIO_s_file()); if (in == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { reason_code = ERR_R_ASN1_LIB; x = d2i_X509_bio(in, NULL); } else if (type == SSL_FILETYPE_PEM) { reason_code = ERR_R_PEM_LIB; x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, ssl->ctx->default_passwd_callback_userdata); } else { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); goto end; } if (x == NULL) { OPENSSL_PUT_ERROR(SSL, reason_code); goto end; } ret = SSL_use_certificate(ssl, x); end: X509_free(x); BIO_free(in); return ret; }
DWORD DirCliDERToX509( PBYTE pCertBytes, DWORD dwLength, X509** ppCert ) { DWORD dwError = 0; BIO *pBioMem = NULL; X509* pCert = NULL; pBioMem = BIO_new_mem_buf(pCertBytes, dwLength); if ( pBioMem == NULL) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_VMAFD_ERROR(dwError); } pCert = d2i_X509_bio(pBioMem, NULL); if (pCert == NULL) { dwError = ERROR_OPEN_FAILED; BAIL_ON_VMAFD_ERROR(dwError); } *ppCert = pCert; cleanup: if (pBioMem) { BIO_free(pBioMem); } return dwError; error: *ppCert = NULL; goto cleanup; }
X509 *https_open_cert(s8 *filepath) { X509 *cert = NULL; BIO *bio_cert = NULL; bio_cert = BIO_new_file(filepath, "r"); if (!bio_cert) { return NULL; } cert = PEM_read_bio_X509(bio_cert, NULL, NULL, NULL); if (!cert) { (void)BIO_reset(bio_cert); cert = d2i_X509_bio(bio_cert, NULL); } BIO_free(bio_cert); return cert; }
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { int j; BIO *in; int ret = 0; X509 *x = NULL; in = BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerrorx(ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { SSLerrorx(ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; x = d2i_X509_bio(in, NULL); } else if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata); } else { SSLerrorx(SSL_R_BAD_SSL_FILETYPE); goto end; } if (x == NULL) { SSLerrorx(j); goto end; } ret = SSL_CTX_use_certificate(ctx, x); end: X509_free(x); BIO_free(in); return (ret); }
Handle<Certificate> Provider_System::getCertFromURI(Handle<std::string> uri, Handle<std::string> format){ LOGGER_FN(); try{ BIO *bioFile = NULL; X509 *hcert = NULL; LOGGER_OPENSSL(BIO_new); bioFile = BIO_new(BIO_s_file()); LOGGER_OPENSSL(BIO_read_filename); if (BIO_read_filename(bioFile, uri->c_str()) > 0){ LOGGER_OPENSSL(BIO_seek); BIO_seek(bioFile, 0); if (strcmp(format->c_str(), "PEM") == 0){ LOGGER_OPENSSL(PEM_read_bio_X509); hcert = PEM_read_bio_X509(bioFile, NULL, NULL, NULL); } else if (strcmp(format->c_str(), "DER") == 0){ LOGGER_OPENSSL(d2i_X509_bio); hcert = d2i_X509_bio(bioFile, NULL); } else{ THROW_EXCEPTION(0, Provider_System, NULL, "Unsupported format. Only PEM | DER"); } } LOGGER_OPENSSL(BIO_free); BIO_free(bioFile); if (!hcert){ THROW_EXCEPTION(0, Provider_System, NULL, "Unable decode cert from PEM/DER"); } else{ return new Certificate(hcert); } } catch (Handle<Exception> e){ THROW_EXCEPTION(0, Provider_System, e, "Error get certificate from URI"); } }
static int sc_oberthur_get_certificate_authority(struct sc_pkcs15_der *der, int *out_authority) { #ifdef ENABLE_OPENSSL X509 *x; BUF_MEM buf_mem; BIO *bio = NULL; BASIC_CONSTRAINTS *bs = NULL; if (!der) return SC_ERROR_INVALID_ARGUMENTS; buf_mem.data = malloc(der->len); if (!buf_mem.data) return SC_ERROR_MEMORY_FAILURE; memcpy(buf_mem.data, der->value, der->len); buf_mem.max = buf_mem.length = der->len; bio = BIO_new(BIO_s_mem()); if(!bio) return SC_ERROR_MEMORY_FAILURE; BIO_set_mem_buf(bio, &buf_mem, BIO_NOCLOSE); x = d2i_X509_bio(bio, 0); BIO_free(bio); if (!x) return SC_ERROR_INVALID_DATA; bs = (BASIC_CONSTRAINTS *)X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL); if (out_authority) *out_authority = (bs && bs->ca); X509_free(x); return SC_SUCCESS; #else return SC_ERROR_NOT_SUPPORTED; #endif }
static X509 *LoadCert(unsigned char *data, size_t len, CertFormat format) { X509 *x509; BIO *bio = BIO_new_mem_buf(data, len); if (bio == NULL) { exit(1); } if (format == PEM) { x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); } else { x509 = d2i_X509_bio(bio, NULL); } BIO_free(bio); return x509; }
static X509 *_load_certificate_from_mem(int format, uint8_t *buffer, uint32_t length, char *password) { X509 *x509 = NULL; BIO *mem = NULL; mem = BIO_new_mem_buf(buffer, length); if (mem != NULL) { switch (format) { case 0 : x509 = d2i_X509_bio(mem, NULL); break; case 1 : x509 = PEM_read_bio_X509(mem, NULL, NULL, NULL); break; case 2 : { PKCS12 *p12 = d2i_PKCS12_bio(mem, NULL); PKCS12_parse(p12, password, NULL, &x509, NULL); PKCS12_free(p12); } break; } BIO_free(mem); } else { DEBUG_ERR_MSG("X509_LOOKUP_load_file failed"); } return x509; }
XSECCryptoKey * InteropResolver::openCertURI(const XMLCh * uri) { // Open a certificate from a file URI relative to the signature file BIO * bioCert; if ((bioCert = BIO_new(BIO_s_file())) == NULL) { return NULL; } safeBuffer fname; char * u = XMLString::transcode(uri); fname.sbTranscodeIn(mp_baseURI); fname.sbStrcatIn("/"); fname.sbStrcatIn(u); XSEC_RELEASE_XMLCH(u); #if defined(_WIN32) reverseSlash(fname); #endif if (BIO_read_filename(bioCert, fname.rawCharBuffer()) <= 0) { return NULL; } X509 * x509 = d2i_X509_bio(bioCert, NULL); BIO_free(bioCert); OpenSSLCryptoX509 oX509(x509); X509_free(x509); return oX509.clonePublicKey(); }
X509 * x509_from_asn(u_char *asn, u_int len) { BIO *certh; X509 *scert = 0; certh = BIO_new(BIO_s_mem()); if (!certh) { log_error("x509_from_asn: BIO_new (BIO_s_mem ()) failed"); return 0; } if (BIO_write(certh, asn, len) == -1) { log_error("x509_from_asn: BIO_write failed\n"); goto end; } scert = d2i_X509_bio(certh, NULL); if (!scert) { log_print("x509_from_asn: d2i_X509_bio failed\n"); goto end; } end: BIO_free(certh); return scert; }
int ProcwatcherIMV::loadX509Cert(TNC_BufferReference message, TNC_UInt32 length) { LOG4CXX_TRACE(logger, "loadX509Cert()"); BIO *bio = BIO_new_mem_buf(message, length); if (bio == NULL) { LOG4CXX_FATAL(logger, "Could not create BIO object"); return -1; } if (isASN1(message, length)) { x509Cert = d2i_X509_bio(bio, NULL); } else { x509Cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); } if (x509Cert == NULL) { LOG4CXX_FATAL(logger, "Could not create X509 object"); BIO_free(bio); return -1; } LOG4CXX_INFO(logger, "X509 certificate successfully received"); BIO_free(bio); return 0; }
bool mailcore::checkCertificate(mailstream * stream, String * hostname) { #if __APPLE__ bool result = false; CFStringRef hostnameCFString; SecPolicyRef policy; CFMutableArrayRef certificates; SecTrustRef trust = NULL; SecTrustResultType trustResult; OSStatus status; carray * cCerts = mailstream_get_certificate_chain(stream); if (cCerts == NULL) { fprintf(stderr, "warning: No certificate chain retrieved"); goto err; } hostnameCFString = CFStringCreateWithCharacters(NULL, (const UniChar *) hostname->unicodeCharacters(), hostname->length()); policy = SecPolicyCreateSSL(true, hostnameCFString); certificates = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for(unsigned int i = 0 ; i < carray_count(cCerts) ; i ++) { MMAPString * str; str = (MMAPString *) carray_get(cCerts, i); CFDataRef data = CFDataCreate(NULL, (const UInt8 *) str->str, (CFIndex) str->len); SecCertificateRef cert = SecCertificateCreateWithData(NULL, data); CFArrayAppendValue(certificates, cert); CFRelease(data); CFRelease(cert); } static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // The below API calls are not thread safe. We're making sure not to call the concurrently. pthread_mutex_lock(&lock); status = SecTrustCreateWithCertificates(certificates, policy, &trust); if (status != noErr) { pthread_mutex_unlock(&lock); goto free_certs; } status = SecTrustEvaluate(trust, &trustResult); if (status != noErr) { pthread_mutex_unlock(&lock); goto free_certs; } pthread_mutex_unlock(&lock); switch (trustResult) { case kSecTrustResultUnspecified: case kSecTrustResultProceed: // certificate chain is ok result = true; break; default: // certificate chain is invalid break; } CFRelease(trust); free_certs: CFRelease(certificates); mailstream_certificate_chain_free(cCerts); CFRelease(policy); CFRelease(hostnameCFString); err: return result; #else bool result = false; X509_STORE * store = NULL; X509_STORE_CTX * storectx = NULL; STACK_OF(X509) * certificates = NULL; #if defined(ANDROID) || defined(__ANDROID__) DIR * dir = NULL; struct dirent * ent = NULL; FILE * f = NULL; #endif int status; carray * cCerts = mailstream_get_certificate_chain(stream); if (cCerts == NULL) { fprintf(stderr, "warning: No certificate chain retrieved"); goto err; } store = X509_STORE_new(); if (store == NULL) { goto free_certs; } #ifdef _MSC_VER HCERTSTORE systemStore = CertOpenSystemStore(NULL, L"ROOT"); PCCERT_CONTEXT previousCert = NULL; while (1) { PCCERT_CONTEXT nextCert = CertEnumCertificatesInStore(systemStore, previousCert); if (nextCert == NULL) { break; } X509 * openSSLCert = d2i_X509(NULL, (const unsigned char **)&nextCert->pbCertEncoded, nextCert->cbCertEncoded); if (openSSLCert != NULL) { X509_STORE_add_cert(store, openSSLCert); X509_free(openSSLCert); } previousCert = nextCert; } CertCloseStore(systemStore, 0); #elif defined(ANDROID) || defined(__ANDROID__) dir = opendir("/system/etc/security/cacerts"); while (ent = readdir(dir)) { if (ent->d_name[0] == '.') { continue; } char filename[1024]; snprintf(filename, sizeof(filename), "/system/etc/security/cacerts/%s", ent->d_name); f = fopen(filename, "rb"); if (f != NULL) { X509 * cert = PEM_read_X509(f, NULL, NULL, NULL); if (cert != NULL) { X509_STORE_add_cert(store, cert); X509_free(cert); } fclose(f); } } closedir(dir); #endif status = X509_STORE_set_default_paths(store); if (status != 1) { printf("Error loading the system-wide CA certificates"); } certificates = sk_X509_new_null(); for(unsigned int i = 0 ; i < carray_count(cCerts) ; i ++) { MMAPString * str; str = (MMAPString *) carray_get(cCerts, i); if (str == NULL) { goto free_certs; } BIO *bio = BIO_new_mem_buf((void *) str->str, str->len); X509 *certificate = d2i_X509_bio(bio, NULL); BIO_free(bio); if (!sk_X509_push(certificates, certificate)) { goto free_certs; } } storectx = X509_STORE_CTX_new(); if (storectx == NULL) { goto free_certs; } status = X509_STORE_CTX_init(storectx, store, sk_X509_value(certificates, 0), certificates); if (status != 1) { goto free_certs; } status = X509_verify_cert(storectx); if (status == 1) { result = true; } free_certs: mailstream_certificate_chain_free(cCerts); if (certificates != NULL) { sk_X509_pop_free((STACK_OF(X509) *) certificates, X509_free); }
struct ibuf * dsa_setkey(struct iked_dsa *dsa, void *key, size_t keylen, uint8_t type) { BIO *rawcert = NULL; X509 *cert = NULL; RSA *rsa = NULL; EVP_PKEY *pkey = NULL; ibuf_release(dsa->dsa_keydata); if ((dsa->dsa_keydata = ibuf_new(key, keylen)) == NULL) { log_debug("%s: alloc signature key", __func__); return (NULL); } if ((rawcert = BIO_new_mem_buf(key, keylen)) == NULL) goto err; switch (type) { case IKEV2_CERT_X509_CERT: if ((cert = d2i_X509_bio(rawcert, NULL)) == NULL) goto sslerr; if ((pkey = X509_get_pubkey(cert)) == NULL) goto sslerr; dsa->dsa_cert = cert; dsa->dsa_key = pkey; break; case IKEV2_CERT_RSA_KEY: if (dsa->dsa_sign) { if ((rsa = d2i_RSAPrivateKey_bio(rawcert, NULL)) == NULL) goto sslerr; } else { if ((rsa = d2i_RSAPublicKey_bio(rawcert, NULL)) == NULL) goto sslerr; } if ((pkey = EVP_PKEY_new()) == NULL) goto sslerr; if (!EVP_PKEY_set1_RSA(pkey, rsa)) goto sslerr; RSA_free(rsa); /* pkey now has the reference */ dsa->dsa_cert = NULL; dsa->dsa_key = pkey; break; default: if (dsa->dsa_hmac) break; log_debug("%s: unsupported key type", __func__); goto err; } return (dsa->dsa_keydata); sslerr: ca_sslerror(__func__); err: log_debug("%s: error", __func__); if (rsa != NULL) RSA_free(rsa); if (pkey != NULL) EVP_PKEY_free(pkey); if (cert != NULL) X509_free(cert); if (rawcert != NULL) BIO_free(rawcert); ibuf_release(dsa->dsa_keydata); return (NULL); }
int main(int argc, char **argv) { //ENGINE *e = NULL; int c, host_port = 80, count = 1; char *host_name, *p, *dir_name = NULL; char http_string[16384]; struct http_reply reply; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; struct scep scep_t; FILE *fp = NULL; BIO *bp; STACK_OF(X509) *nextcara = NULL; X509 *cert=NULL; PKCS7 p7; int i; int required_option_space; #ifdef WIN32 WORD wVersionRequested; WSADATA wsaData; int err; //printf("Starting sscep\n"); //fprintf(stdout, "%s: starting sscep on WIN32, sscep version %s\n", pname, VERSION); wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return; } /* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return; } #endif /* Initialize scep layer */ init_scep(); /* Set program name */ pname = argv[0]; /* Set timeout */ timeout = TIMEOUT; /* Check operation parameter */ if (!argv[1]) { usage(); } else if (!strncmp(argv[1], "getca", 5)) { operation_flag = SCEP_OPERATION_GETCA; } else if (!strncmp(argv[1], "enroll", 6)) { operation_flag = SCEP_OPERATION_ENROLL; } else if (!strncmp(argv[1], "getcert", 7)) { operation_flag = SCEP_OPERATION_GETCERT; } else if (!strncmp(argv[1], "getcrl", 6)) { operation_flag = SCEP_OPERATION_GETCRL; } else if (!strncmp(argv[1], "getnextca", 9)) { operation_flag = SCEP_OPERATION_GETNEXTCA; } else { fprintf(stderr, "%s: missing or illegal operation parameter\n", argv[0]); usage(); } /* Skip first parameter and parse the rest of the command */ optind++; while ((c = getopt(argc, argv, "c:C:de:E:f:g:hF:i:k:K:l:L:n:O:p:r:Rs:S:t:T:u:vw:m:HM:")) != -1) switch(c) { case 'c': c_flag = 1; c_char = optarg; break; case 'C': C_flag = 1; C_char = optarg; break; case 'd': d_flag = 1; break; case 'e': e_flag = 1; e_char = optarg; break; case 'E': E_flag = 1; E_char = optarg; break; case 'F': F_flag = 1; F_char = optarg; break; case 'f': f_flag = 1; f_char = optarg; break; case 'g': g_flag = 1; g_char = optarg; break; case 'h'://TODO change to eg. ID --inform=ID h_flag = 1; break; case 'H': H_flag = 1; break; case 'i': i_flag = 1; i_char = optarg; break; case 'k': k_flag = 1; k_char = optarg; break; case 'K': K_flag = 1; K_char = optarg; break; case 'l': l_flag = 1; l_char = optarg; break; case 'L': L_flag = 1; L_char = optarg; break; case 'm': m_flag = 1; m_char = optarg; break; case 'M': if(!M_flag) { /* if this is the first time the option appears, create a * new string. */ required_option_space = strlen(optarg) + 1; M_char = malloc(required_option_space); if(!M_char) error_memory(); strncpy(M_char, optarg, required_option_space); // set the flag, so we already have a string M_flag = 1; } else { /* we already have a string, just extend it. */ // old part + new part + &-sign + null byte required_option_space = strlen(M_char) + strlen(optarg) + 2; M_char = realloc(M_char, required_option_space); if(!M_char) error_memory(); strncat(M_char, "&", 1); strncat(M_char, optarg, strlen(optarg)); } break; case 'n': n_flag = 1; n_num = atoi(optarg); break; case 'O': O_flag = 1; O_char = optarg; break; case 'p': p_flag = 1; p_char = optarg; break; case 'r': r_flag = 1; r_char = optarg; break; case 'R': R_flag = 1; break; case 's': s_flag = 1; /*s_char = optarg;*/ s_char = handle_serial(optarg); break; case 'S': S_flag = 1; S_char = optarg; break; case 't': t_flag = 1; t_num = atoi(optarg); break; case 'T': T_flag = 1; T_num = atoi(optarg); break; case 'u': u_flag = 1; url_char = optarg; break; case 'v': v_flag = 1; break; case 'w': w_flag = 1; w_char = optarg; break; default: printf("argv: %s\n", argv[optind]); usage(); } argc -= optind; argv += optind; /* If we debug, include verbose messages also */ if (d_flag) v_flag = 1; if(f_char){ scep_conf_init(f_char); }else{ scep_conf = NULL; //moved init to here otherwise compile error on windows } /* Read in the configuration file: */ /*if (f_char) { #ifdef WIN32 if ((fopen_s(&fp, f_char, "r"))) #else if (!(fp = fopen(f_char, "r"))) #endif fprintf(stderr, "%s: cannot open %s\n", pname, f_char); else { init_config(fp); (void)fclose(fp); } }*/ if (v_flag) fprintf(stdout, "%s: starting sscep, version %s\n", pname, VERSION); /* * Create a new SCEP transaction and self-signed * certificate based on cert request */ if (v_flag) fprintf(stdout, "%s: new transaction\n", pname); new_transaction(&scep_t); /*enable Engine Support */ if (g_flag) { scep_t.e = scep_engine_init(scep_t.e); } /* * Check argument logic. */ if (!c_flag) { if (operation_flag == SCEP_OPERATION_GETCA) { fprintf(stderr, "%s: missing CA certificate filename (-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } else { fprintf(stderr, "%s: missing CA certificate (-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (operation_flag == SCEP_OPERATION_GETNEXTCA) { fprintf(stderr, "%s: missing nextCA certificate target filename (-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } else { fprintf(stderr, "%s: missing nextCA certificate target filename(-c)\n", pname); exit (SCEP_PKISTATUS_ERROR); } } if (!C_flag) { if (operation_flag == SCEP_OPERATION_GETNEXTCA) { fprintf(stderr, "%s: missing nextCA certificate chain filename (-C)\n", pname); exit (SCEP_PKISTATUS_ERROR); } } if (operation_flag == SCEP_OPERATION_ENROLL) { if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!r_flag) { fprintf(stderr, "%s: missing request (-r)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n",pname); exit (SCEP_PKISTATUS_ERROR); } /* Set polling limits */ if (!n_flag) n_num = MAX_POLL_COUNT; if (!t_flag) t_num = POLL_TIME; if (!T_flag) T_num = MAX_POLL_TIME; } if (operation_flag == SCEP_OPERATION_GETCERT) { if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!s_flag) { fprintf(stderr, "%s: missing serial no (-s)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (!w_flag) { fprintf(stderr, "%s: missing cert file (-w)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n",pname); exit (SCEP_PKISTATUS_ERROR); } } if (operation_flag == SCEP_OPERATION_GETCRL) { if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!w_flag) { fprintf(stderr, "%s: missing crl file (-w)\n",pname); exit (SCEP_PKISTATUS_ERROR); } if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n",pname); exit (SCEP_PKISTATUS_ERROR); } } /* Break down the URL */ if (!u_flag) { fprintf(stderr, "%s: missing URL (-u)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (strncmp(url_char, "http://", 7) && !p_flag) { fprintf(stderr, "%s: illegal URL %s\n", pname, url_char); exit (SCEP_PKISTATUS_ERROR); } if (p_flag) { #ifdef WIN32 host_name = _strdup(p_char); #else host_name = strdup(p_char); #endif dir_name = url_char; } /* Break down the URL */ if (!u_flag) { fprintf(stderr, "%s: missing URL (-u)\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (strncmp(url_char, "http://", 7) && !p_flag) { fprintf(stderr, "%s: illegal URL %s\n", pname, url_char); exit (SCEP_PKISTATUS_ERROR); } if (p_flag) { #ifdef WIN32 host_name = _strdup(p_char); #else host_name = strdup(p_char); #endif dir_name = url_char; } #ifdef WIN32 else if (!(host_name = _strdup(url_char + 7))) #else else if (!(host_name = strdup(url_char + 7))) #endif error_memory(); p = host_name; c = 0; while (*p != '\0') { if (*p == '/' && !p_flag && !c) { *p = '\0'; if (*(p+1)) dir_name = p + 1; c = 1; } if (*p == ':') { *p = '\0'; if (*(p+1)) host_port = atoi(p+1); } p++; } if (!dir_name) { fprintf(stderr, "%s: illegal URL %s\n", pname, url_char); exit (SCEP_PKISTATUS_ERROR); } if (host_port < 1 || host_port > 65550) { fprintf(stderr, "%s: illegal port number %d\n", pname, host_port); exit (SCEP_PKISTATUS_ERROR); } if (v_flag) { fprintf(stdout, "%s: hostname: %s\n", pname, host_name); fprintf(stdout, "%s: directory: %s\n", pname, dir_name); fprintf(stdout, "%s: port: %d\n", pname, host_port); } /* Check algorithms */ if (!E_flag) { enc_alg = (EVP_CIPHER *)EVP_des_cbc(); } else if (!strncmp(E_char, "blowfish", 8)) { enc_alg = (EVP_CIPHER *)EVP_bf_cbc(); } else if (!strncmp(E_char, "des", 3)) { enc_alg = (EVP_CIPHER *)EVP_des_cbc(); } else if (!strncmp(E_char, "3des", 4)) { enc_alg = (EVP_CIPHER *)EVP_des_ede3_cbc(); } else if (!strncmp(E_char, "aes", 3)) { enc_alg = (EVP_CIPHER *)EVP_aes_256_cbc(); } else { fprintf(stderr, "%s: unsupported algorithm: %s\n", pname, E_char); exit (SCEP_PKISTATUS_ERROR); } if (!S_flag) { sig_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(S_char, "md5", 3)) { sig_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(S_char, "sha1", 4)) { sig_alg = (EVP_MD *)EVP_sha1(); } else { fprintf(stderr, "%s: unsupported algorithm: %s\n", pname, S_char); exit (SCEP_PKISTATUS_ERROR); } /* Fingerprint algorithm */ if (!F_flag) { fp_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(F_char, "md5", 3)) { fp_alg = (EVP_MD *)EVP_md5(); } else if (!strncmp(F_char, "sha1", 4)) { fp_alg = (EVP_MD *)EVP_sha1(); } else { fprintf(stderr, "%s: unsupported algorithm: %s\n", pname, F_char); exit (SCEP_PKISTATUS_ERROR); } /* * Switch to operation specific code */ switch(operation_flag) { case SCEP_OPERATION_GETCA: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETCA\n", pname); /* Set CA identifier */ if (!i_flag) i_char = CA_IDENTIFIER; /* Forge the HTTP message */ if(!M_flag){ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetCACert&message=%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char); }else{ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetCACert&message=%s&%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char, M_char); } if (d_flag){ printf("%s: requesting CA certificate\n", pname); fprintf(stdout, "%s: scep msg: %s", pname, http_string); } /* * Send http message. * Response is written to http_response struct "reply". */ reply.payload = NULL; if ((c = send_msg (&reply, http_string, host_name, host_port, operation_flag)) == 1) { fprintf(stderr, "%s: error while sending " "message\n", pname); exit (SCEP_PKISTATUS_NET); } if (reply.payload == NULL) { fprintf(stderr, "%s: no data, perhaps you " "should define CA identifier (-i)\n", pname); exit (SCEP_PKISTATUS_SUCCESS); } if (v_flag){ printf("%s: valid response from server\n", pname); } if (reply.type == SCEP_MIME_GETCA_RA) { /* XXXXXXXXXXXXXXXXXXXXX chain not verified */ write_ca_ra(&reply); } /* Read payload as DER X.509 object: */ bp = BIO_new_mem_buf(reply.payload, reply.bytes); cacert = d2i_X509_bio(bp, NULL); /* Read and print certificate information */ if (!X509_digest(cacert, fp_alg, md, &n)) { ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } if (v_flag){ printf("%s: %s fingerprint: ", pname, OBJ_nid2sn(EVP_MD_type(fp_alg))); for (c = 0; c < (int)n; c++) { printf("%02X%c",md[c], (c + 1 == (int)n) ?'\n':':'); } } /* Write PEM-formatted file: */ #ifdef WIN32 if ((fopen_s(&fp,c_char , "w"))) #else if (!(fp = fopen(c_char, "w"))) #endif { fprintf(stderr, "%s: cannot open CA file for " "writing\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (PEM_write_X509(fp, c_char) != 1) { fprintf(stderr, "%s: error while writing CA " "file\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } if (v_flag) printf("%s: CA certificate written as %s\n", pname, c_char); (void)fclose(fp); pkistatus = SCEP_PKISTATUS_SUCCESS; break; case SCEP_OPERATION_GETNEXTCA: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETNEXTCA\n", pname); /* Set CA identifier */ if (!i_flag) i_char = CA_IDENTIFIER; /* Forge the HTTP message */ if(!M_flag){ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetNextCACert&message=%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char); }else{ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetNextCACert&message=%s&%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, i_char, M_char); } if (d_flag){ printf("%s: requesting nextCA certificate\n", pname); fprintf(stdout, "%s: scep msg: %s", pname, http_string); } /* * Send http message. * Response is written to http_response struct "reply". */ reply.payload = NULL; if ((c = send_msg (&reply, http_string, host_name, host_port, operation_flag)) == 1) { if(v_flag){ fprintf(stderr, "%s: error while sending " "message\n", pname); fprintf(stderr, "%s: getnextCA might be not available" "\n", pname); } exit (SCEP_PKISTATUS_NET); } if (reply.payload == NULL) { fprintf(stderr, "%s: no data, perhaps you " "there is no nextCA available\n", pname); exit (SCEP_PKISTATUS_SUCCESS); } if(d_flag) printf("%s: valid response from server\n", pname); if (reply.type == SCEP_MIME_GETNEXTCA) { /* XXXXXXXXXXXXXXXXXXXXX chain not verified */ //write_ca_ra(&reply); /* Set the whole struct as 0 */ memset(&scep_t, 0, sizeof(scep_t)); scep_t.reply_payload = reply.payload; scep_t.reply_len = reply.bytes; scep_t.request_type = SCEP_MIME_GETNEXTCA; pkcs7_verify_unwrap(&scep_t , C_char); //pkcs7_unwrap(&scep_t); } /* Get certs */ p7 = *(scep_t.reply_p7); nextcara = scep_t.reply_p7->d.sign->cert; if (v_flag) { printf ("verify and unwrap: found %d cert(s)\n", sk_X509_num(nextcara)); } for (i = 0; i < sk_X509_num(nextcara); i++) { char buffer[1024]; char name[1024]; memset(buffer, 0, 1024); memset(name, 0, 1024); cert = sk_X509_value(nextcara, i); if (v_flag) { printf("%s: found certificate with\n" " subject: '%s'\n", pname, X509_NAME_oneline(X509_get_subject_name(cert), buffer, sizeof(buffer))); printf(" issuer: %s\n", X509_NAME_oneline(X509_get_issuer_name(cert), buffer, sizeof(buffer))); } /* Create name */ snprintf(name, 1024, "%s-%d", c_char, i); /* Write PEM-formatted file: */ if (!(fp = fopen(name, "w"))) { fprintf(stderr, "%s: cannot open cert file for writing\n", pname); exit (SCEP_PKISTATUS_FILE); } if (v_flag) printf("%s: writing cert\n", pname); if (d_flag) PEM_write_X509(stdout, cert); if (PEM_write_X509(fp, cert) != 1) { fprintf(stderr, "%s: error while writing certificate " "file\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_FILE); } if(v_flag) printf("%s: certificate written as %s\n", pname, name); (void)fclose(fp); } pkistatus = SCEP_PKISTATUS_SUCCESS; break; case SCEP_OPERATION_GETCERT: case SCEP_OPERATION_GETCRL: /* Read local certificate */ if (!l_flag) { fprintf(stderr, "%s: missing local cert (-l)\n", pname); exit (SCEP_PKISTATUS_FILE); } read_cert(&localcert, l_char); case SCEP_OPERATION_ENROLL: /* * Read in CA cert, private key and certificate * request in global variables. */ read_ca_cert(); if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n", pname); exit (SCEP_PKISTATUS_FILE); } if(scep_conf != NULL) { sscep_engine_read_key_new(&rsa, k_char, scep_t.e); } else { read_key(&rsa, k_char); } if ((K_flag && !O_flag) || (!K_flag && O_flag)) { fprintf(stderr, "%s: -O also requires -K (and vice-versa)\n", pname); exit (SCEP_PKISTATUS_FILE); } if (K_flag) { //TODO auf hwcrhk prfen? if(scep_conf != NULL) { sscep_engine_read_key_old(&renewal_key, K_char, scep_t.e); } else { read_key(&renewal_key, K_char); } } if (O_flag) { read_cert(&renewal_cert, O_char); } if (operation_flag == SCEP_OPERATION_ENROLL) { read_request(); scep_t.transaction_id = key_fingerprint(request); if (v_flag) { printf("%s: Read request with transaction id: %s\n", pname, scep_t.transaction_id); } } if (operation_flag != SCEP_OPERATION_ENROLL) goto not_enroll; if (! O_flag) { if (v_flag) fprintf(stdout, "%s: generating selfsigned " "certificate\n", pname); new_selfsigned(&scep_t); } else { /* Use existing certificate */ scep_t.signercert = renewal_cert; scep_t.signerkey = renewal_key; } /* Write the selfsigned certificate if requested */ if (L_flag) { /* Write PEM-formatted file: */ #ifdef WIN32 if ((fopen_s(&fp, L_char, "w"))) { #else if (!(fp = fopen(L_char, "w"))) { #endif fprintf(stderr, "%s: cannot open " "file for writing\n", pname); exit (SCEP_PKISTATUS_ERROR); } if (PEM_write_X509(fp,scep_t.signercert) != 1) { fprintf(stderr, "%s: error while " "writing certificate file\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } printf("%s: selfsigned certificate written " "as %s\n", pname, L_char); (void)fclose(fp); } /* Write issuer name and subject (GetCertInitial): */ if (!(scep_t.ias_getcertinit->subject = X509_REQ_get_subject_name(request))) { fprintf(stderr, "%s: error getting subject " "for GetCertInitial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } not_enroll: if (!(scep_t.ias_getcertinit->issuer = X509_get_issuer_name(cacert))) { fprintf(stderr, "%s: error getting issuer " "for GetCertInitial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } /* Write issuer name and serial (GETC{ert,rl}): */ scep_t.ias_getcert->issuer = scep_t.ias_getcertinit->issuer; scep_t.ias_getcrl->issuer = scep_t.ias_getcertinit->issuer; if (!(scep_t.ias_getcrl->serial = X509_get_serialNumber(cacert))) { fprintf(stderr, "%s: error getting serial " "for GetCertInitial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } /* User supplied serial number */ if (s_flag) { BIGNUM *bn; ASN1_INTEGER *ai; int len = BN_dec2bn(&bn , s_char); if (!len || !(ai = BN_to_ASN1_INTEGER(bn, NULL))) { fprintf(stderr, "%s: error converting serial\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_SS); } scep_t.ias_getcert->serial = ai; } break; } switch(operation_flag) { case SCEP_OPERATION_ENROLL: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_ENROLL\n", pname); /* Resum mode: set GetCertInitial */ if (R_flag) { if (n_num == 0) exit (SCEP_PKISTATUS_SUCCESS); printf("%s: requesting certificate (#1)\n", pname); scep_t.request_type = SCEP_REQUEST_GETCERTINIT; count++; } else { printf("%s: sending certificate request\n", pname); scep_t.request_type = SCEP_REQUEST_PKCSREQ; } break; case SCEP_OPERATION_GETCERT: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETCERT\n", pname); scep_t.request_type = SCEP_REQUEST_GETCERT; printf("%s: requesting certificate\n",pname); break; case SCEP_OPERATION_GETCRL: if (v_flag) fprintf(stdout, "%s: SCEP_OPERATION_GETCRL\n", pname); scep_t.request_type = SCEP_REQUEST_GETCRL; printf("%s: requesting crl\n",pname); break; } /* Enter polling loop */ while (scep_t.pki_status != SCEP_PKISTATUS_SUCCESS) { /* create payload */ pkcs7_wrap(&scep_t); /* URL-encode */ p = url_encode((char *)scep_t.request_payload, scep_t.request_len); /*Test mode print SCEP request and don't send it*/ if(m_flag){ /* Write output file : */ #ifdef WIN32 if ((fopen_s(&fp, m_char, "w"))) #else if (!(fp = fopen(m_char, "w"))) #endif { fprintf(stderr, "%s: cannot open output file for " "writing\n", m_char); }else { printf("%s: writing PEM fomatted PKCS#7\n", pname); PEM_write_PKCS7(fp, scep_t.request_p7); } //printf("Print SCEP Request:\n %s\n",scep_t.request_payload); return 0; } /* Forge the HTTP message */ /* snprintf(http_string, sizeof(http_string), "GET %s%s?operation=" "PKIOperation&message=" "%s HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, p);*/ if(!M_flag){ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=PKIOperation&message=%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, p); }else{ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=PKIOperation&message=%s&%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,p, M_char); } if (d_flag) fprintf(stdout, "%s: scep msg: %s", pname, http_string); /* send http */ reply.payload = NULL; if ((c = send_msg (&reply, http_string, host_name, host_port, operation_flag)) == 1) { fprintf(stderr, "%s: error while sending " "message\n", pname); exit (SCEP_PKISTATUS_NET); } /* Verisign Onsite returns strange reply... * XXXXXXXXXXXXXXXXXXX */ if ((reply.status == 200) && (reply.payload == NULL)) { /* scep_t.pki_status = SCEP_PKISTATUS_PENDING; break; */ exit (SCEP_PKISTATUS_ERROR); } printf("%s: valid response from server\n", pname); /* Check payload */ scep_t.reply_len = reply.bytes; scep_t.reply_payload = (unsigned char *)reply.payload; pkcs7_unwrap(&scep_t); pkistatus = scep_t.pki_status; switch(scep_t.pki_status) { case SCEP_PKISTATUS_SUCCESS: break; case SCEP_PKISTATUS_PENDING: /* Check time limits */ if (((t_num * count) >= T_num) || (count > n_num)) { exit (pkistatus); } scep_t.request_type = SCEP_REQUEST_GETCERTINIT; /* Wait for poll interval */ if (v_flag) printf("%s: waiting for %d secs\n", pname, t_num); sleep(t_num); printf("%s: requesting certificate " "(#%d)\n", pname, count); /* Add counter */ count++; break; case SCEP_PKISTATUS_FAILURE: /* Handle failure */ switch (scep_t.fail_info) { case SCEP_FAILINFO_BADALG: exit (SCEP_PKISTATUS_BADALG); case SCEP_FAILINFO_BADMSGCHK: exit (SCEP_PKISTATUS_BADMSGCHK); case SCEP_FAILINFO_BADREQ: exit (SCEP_PKISTATUS_BADREQ); case SCEP_FAILINFO_BADTIME: exit (SCEP_PKISTATUS_BADTIME); case SCEP_FAILINFO_BADCERTID: exit (SCEP_PKISTATUS_BADCERTID); /* Shouldn't be there... */ default: exit (SCEP_PKISTATUS_ERROR); } default: fprintf(stderr, "%s: unknown " "pkiStatus\n", pname); exit (SCEP_PKISTATUS_ERROR); } } /* We got SUCCESS, analyze the reply */ switch (scep_t.request_type) { /* Local certificate */ case SCEP_REQUEST_PKCSREQ: case SCEP_REQUEST_GETCERTINIT: write_local_cert(&scep_t); break; /* Other end entity certificate */ case SCEP_REQUEST_GETCERT: write_other_cert(&scep_t); break; break; /* CRL */ case SCEP_REQUEST_GETCRL: write_crl(&scep_t); break; } //TODO //richtiger ort für disable?? // if(e){ // ENGINE_finish(*e); // ENGINE_free(*e); // hwEngine = NULL; // ENGINE_cleanup(); // } // return (pkistatus); } void usage() { fprintf(stdout, "\nsscep version %s\n\n" , VERSION); fprintf(stdout, "Usage: %s OPERATION [OPTIONS]\n" "\nAvailable OPERATIONs are\n" " getca Get CA/RA certificate(s)\n" " getnextca Get next CA/RA certificate(s)\n" " enroll Enroll certificate\n" " getcert Query certificate\n" " getcrl Query CRL\n" "\nGeneral OPTIONS\n" " -u <url> SCEP server URL\n" " -p <host:port> Use proxy server at host:port\n" " -M <string> Monitor Information String name=value&name=value ...\n" " -g Enable Engine support\n" " -h Keyforme=ID. \n"//TODO " -f <file> Use configuration file\n" " -c <file> CA certificate file (write if OPERATION is getca or getnextca)\n" " -E <name> PKCS#7 encryption algorithm (des|3des|blowfish|aes)\n" " -S <name> PKCS#7 signature algorithm (md5|sha1)\n" " -v Verbose operation\n" " -d Debug (even more verbose operation)\n" "\nOPTIONS for OPERATION getca are\n" " -i <string> CA identifier string\n" " -F <name> Fingerprint algorithm\n" "\nOPTIONS for OPERATION getnextca are\n" " -C <file> Local certificate chain file for signature verification in PEM format \n" " -F <name> Fingerprint algorithm\n" " -c <file> CA certificate file (write if OPERATION is getca or getnextca)\n" " -w <file> Write signer certificate in file (optional) \n" "\nOPTIONS for OPERATION enroll are\n" " -k <file> Private key file\n" " -r <file> Certificate request file\n" " -K <file> Signature private key file, use with -O\n" " -O <file> Signature certificate (used instead of self-signed)\n" " -l <file> Write enrolled certificate in file\n" " -e <file> Use different CA cert for encryption\n" " -L <file> Write selfsigned certificate in file\n" " -t <secs> Polling interval in seconds\n" " -T <secs> Max polling time in seconds\n" " -n <count> Max number of GetCertInitial requests\n" " -R Resume interrupted enrollment\n" "\nOPTIONS for OPERATION getcert are\n" " -k <file> Private key file\n" " -l <file> Local certificate file\n" " -s <number> Certificate serial number\n" " -w <file> Write certificate in file\n" "\nOPTIONS for OPERATION getcrl are\n" " -k <file> Private key file\n" " -l <file> Local certificate file\n" " -w <file> Write CRL in file\n\n", pname); exit(0); }
static int sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) { sc_card_t *card = p15card->card; unsigned char buff[128]; int r, i; sc_path_t tmppath; set_string (&p15card->tokeninfo->label, "ID-kaart"); set_string (&p15card->tokeninfo->manufacturer_id, "AS Sertifitseerimiskeskus"); /* Select application directory */ sc_format_path ("3f00eeee5044", &tmppath); r = sc_select_file (card, &tmppath, NULL); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "select esteid PD failed"); /* read the serial (document number) */ r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "read document number failed"); buff[r] = '\0'; set_string (&p15card->tokeninfo->serial_number, (const char *) buff); p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION | SC_PKCS15_TOKEN_EID_COMPLIANT | SC_PKCS15_TOKEN_READONLY; /* add certificates */ for (i = 0; i < 2; i++) { static const char *esteid_cert_names[2] = { "Isikutuvastus", "Allkirjastamine"}; static char const *esteid_cert_paths[2] = { "3f00eeeeaace", "3f00eeeeddce"}; static int esteid_cert_ids[2] = {1, 2}; struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; memset(&cert_info, 0, sizeof(cert_info)); memset(&cert_obj, 0, sizeof(cert_obj)); cert_info.id.value[0] = esteid_cert_ids[i]; cert_info.id.len = 1; sc_format_path(esteid_cert_paths[i], &cert_info.path); strlcpy(cert_obj.label, esteid_cert_names[i], sizeof(cert_obj.label)); r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if (r < 0) return SC_ERROR_INTERNAL; #ifdef ENABLE_OPENSSL if (i == 0) { BIO *mem = NULL; X509 *x509 = NULL; sc_pkcs15_cert_t *cert; char cardholder_name[64]; unsigned char *tmp = NULL; r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); if (r == SC_SUCCESS) { mem = BIO_new_mem_buf(cert->data.value, cert->data.len); if (!mem) { sc_pkcs15_free_certificate(cert); return SC_ERROR_INTERNAL; } x509 = d2i_X509_bio(mem, NULL); BIO_free(mem); sc_pkcs15_free_certificate(cert); if (!x509) return SC_ERROR_INTERNAL; r = X509_NAME_get_index_by_NID(X509_get_subject_name(x509), NID_commonName, -1); if (r >= 0) { X509_NAME_ENTRY *ne; ASN1_STRING *a_str; ne = X509_NAME_get_entry(X509_get_subject_name(x509), r); if (!ne) { X509_free(x509); return SC_ERROR_INTERNAL; } a_str = X509_NAME_ENTRY_get_data(ne); if (!a_str) { X509_free(x509); return SC_ERROR_INTERNAL; } r = ASN1_STRING_to_UTF8(&tmp, a_str); if (r > 0) { if ((unsigned)r > sizeof(cardholder_name) - 1) r = sizeof(cardholder_name) -1; memcpy(cardholder_name, tmp, r); cardholder_name[r] = '\0'; set_string(&p15card->tokeninfo->label, cardholder_name); OPENSSL_free(tmp); } } X509_free(x509); } } #endif } /* the file with key pin info (tries left) */ sc_format_path ("3f000016", &tmppath); r = sc_select_file (card, &tmppath, NULL); if (r < 0) return SC_ERROR_INTERNAL; /* add pins */ for (i = 0; i < 3; i++) { unsigned char tries_left; static const char *esteid_pin_names[3] = { "PIN1", "PIN2", "PUK" }; static const int esteid_pin_min[3] = {4, 5, 8}; static const int esteid_pin_ref[3] = {1, 2, 0}; static const int esteid_pin_authid[3] = {1, 2, 3}; static const int esteid_pin_flags[3] = {0, 0, SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN}; struct sc_pkcs15_auth_info pin_info; struct sc_pkcs15_object pin_obj; memset(&pin_info, 0, sizeof(pin_info)); memset(&pin_obj, 0, sizeof(pin_obj)); /* read the number of tries left for the PIN */ r = sc_read_record (card, i + 1, buff, sizeof(buff), SC_RECORD_BY_REC_NR); if (r < 0) return SC_ERROR_INTERNAL; tries_left = buff[5]; pin_info.auth_id.len = 1; pin_info.auth_id.value[0] = esteid_pin_authid[i]; pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; pin_info.attrs.pin.reference = esteid_pin_ref[i]; pin_info.attrs.pin.flags = esteid_pin_flags[i]; pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; pin_info.attrs.pin.min_length = esteid_pin_min[i]; pin_info.attrs.pin.stored_length = 12; pin_info.attrs.pin.max_length = 12; pin_info.attrs.pin.pad_char = '\0'; pin_info.tries_left = (int)tries_left; pin_info.max_tries = 3; strlcpy(pin_obj.label, esteid_pin_names[i], sizeof(pin_obj.label)); pin_obj.flags = esteid_pin_flags[i]; /* Link normal PINs with PUK */ if (i < 2) { pin_obj.auth_id.len = 1; pin_obj.auth_id.value[0] = 3; } r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); if (r < 0) return SC_ERROR_INTERNAL; } /* add private keys */ for (i = 0; i < 2; i++) { static int prkey_pin[2] = {1, 2}; static int prkey_usage[2] = { SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_SIGN, SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; static const char *prkey_name[2] = { "Isikutuvastus", "Allkirjastamine"}; struct sc_pkcs15_prkey_info prkey_info; struct sc_pkcs15_object prkey_obj; memset(&prkey_info, 0, sizeof(prkey_info)); memset(&prkey_obj, 0, sizeof(prkey_obj)); prkey_info.id.len = 1; prkey_info.id.value[0] = prkey_pin[i]; prkey_info.usage = prkey_usage[i]; prkey_info.native = 1; prkey_info.key_reference = i + 1; if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) prkey_info.modulus_length = 2048; else prkey_info.modulus_length = 1024; strlcpy(prkey_obj.label, prkey_name[i], sizeof(prkey_obj.label)); prkey_obj.auth_id.len = 1; prkey_obj.auth_id.value[0] = prkey_pin[i]; prkey_obj.user_consent = 0; prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); if (r < 0) return SC_ERROR_INTERNAL; } return SC_SUCCESS; }
int ca_validate_cert(struct iked *env, struct iked_static_id *id, void *data, size_t len) { struct ca_store *store = env->sc_priv; X509_STORE_CTX csc; BIO *rawcert = NULL; X509 *cert = NULL; int ret = -1, result, error; X509_NAME *subject; const char *errstr = "failed"; if (len == 0) { /* Data is already an X509 certificate */ cert = (X509 *)data; } else { /* Convert data to X509 certificate */ if ((rawcert = BIO_new_mem_buf(data, len)) == NULL) goto done; if ((cert = d2i_X509_bio(rawcert, NULL)) == NULL) goto done; } /* Certificate needs a valid subjectName */ if ((subject = X509_get_subject_name(cert)) == NULL) { errstr = "invalid subject"; goto done; } if (id != NULL) { if ((ret = ca_validate_pubkey(env, id, X509_get_pubkey(cert), 0)) == 0) { errstr = "in public key file, ok"; goto done; } switch (id->id_type) { case IKEV2_ID_ASN1_DN: if (ca_x509_subject_cmp(cert, id) < 0) { errstr = "ASN1_DN identifier mismatch"; goto done; } break; default: if (ca_x509_subjectaltname_cmp(cert, id) != 0) { errstr = "invalid subjectAltName extension"; goto done; } break; } } bzero(&csc, sizeof(csc)); X509_STORE_CTX_init(&csc, store->ca_cas, cert, NULL); if (store->ca_cas->param->flags & X509_V_FLAG_CRL_CHECK) { X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK); X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK_ALL); } result = X509_verify_cert(&csc); error = csc.error; X509_STORE_CTX_cleanup(&csc); if (error != 0) { errstr = X509_verify_cert_error_string(error); goto done; } if (!result) { /* XXX should we accept self-signed certificates? */ errstr = "rejecting self-signed certificate"; goto done; } /* Success */ ret = 0; errstr = "ok"; done: if (cert != NULL) log_debug("%s: %s %.100s", __func__, cert->name, errstr); if (rawcert != NULL) { BIO_free(rawcert); if (cert != NULL) X509_free(cert); } return (ret); }
static scepitem_t *readitem(char *transid) { scepitem_t *si; BIO *bio; char filename[1024]; char oneline[1024]; X509_NAME *name; /* allocate a new structure */ si = (scepitem_t *)malloc(sizeof(scepitem_t)); /* first create a copy of the transid */ si->transid = strdup(transid); /* make sure that it has the right length */ si->transid[32] = '\0'; /* find the appropriate file: request or certificate */ switch (itemselect) { case SELECT_PENDING: case SELECT_REJECTED: si->type = ITEM_TYPE_REQ; break; case SELECT_GRANTED: case SELECT_REVOKED: si->type = ITEM_TYPE_CERT; break; } /* create the filename for the item */ snprintf(filename, sizeof(filename), "%s/%s/%s.der", OPENSCEPDIR, selectname[itemselect], si->transid); if (debug) fprintf(stderr, "%s:%d: trying file '%s'\n", __FILE__, __LINE__, filename); /* open the file and read the contents */ bio = BIO_new(BIO_s_file()); if (BIO_read_filename(bio, filename) < 0) { fprintf(stderr, "%s:%d: cannot open file %s\n", __FILE__, __LINE__, filename); return NULL; } switch (si->type) { case ITEM_TYPE_REQ: si->data.req = d2i_X509_REQ_bio(bio, NULL); break; case ITEM_TYPE_CERT: si->data.x509 = d2i_X509_bio(bio, NULL); break; } if (si->data.any == NULL) { fprintf(stderr, "%s:%d: cannot decode item, trans id %s\n", __FILE__, __LINE__, si->transid); ERR_print_errors(bio_err); return NULL; } else { if (debug) BIO_printf(bio_err, "%s:%d: got new item\n", __FILE__, __LINE__); } /* extract key information from request or certificate */ switch (sortorder) { case SORT_TRANSID: si->key = strdup(si->transid); break; case SORT_NAME: name = (si->type == ITEM_TYPE_REQ) ? X509_REQ_get_subject_name(si->data.req) : X509_get_subject_name(si->data.x509); X509_NAME_oneline(name, oneline, sizeof(oneline)); si->key = strdup(oneline); break; case SORT_NOTBEFORE: si->key = asn1_time_to_string(X509_get_notBefore( si->data.x509)); break; case SORT_NOTAFTER: si->key = asn1_time_to_string(X509_get_notAfter(si->data.x509)); break; case SORT_SERIAL: si->key = X509_get_serialNumber(si->data.x509); break; } /* return the completely filled in item */ return si; }