Example #1
1
static Bool
IsPKCS12(const char *file)
{
	Bool ret = TRUE;
	EVP_PKEY *key = NULL;
	X509 *cert = NULL;
	BIO *input;
	PKCS12 *p12;
	int err_reason;
	
	if ((input = BIO_new_file(file, "r")) == NULL){
		if (d2i_PKCS12_bio(input, &p12) == NULL) return FALSE;
	}
	p12 = d2i_PKCS12_bio(input, NULL);
	BIO_free(input);
	if (p12 == NULL) return FALSE;
	
	err_reason = PKCS12_parse(p12, "", &key, &cert, NULL);
	if (err_reason == PKCS12_R_MAC_VERIFY_FAILURE){
		ret = FALSE;
	}
	if (cert){ X509_free(cert); cert = NULL; }
	if (key){ EVP_PKEY_free(key); key = NULL; }
	ERR_clear_error();
	PKCS12_free(p12);

	return ret;
}
Example #2
0
Settings::KeyPair CertWizard::importCert(QByteArray data, const QString &pw) {
	X509 *x509 = NULL;
	EVP_PKEY *pkey = NULL;
	PKCS12 *pkcs = NULL;
	BIO *mem = NULL;
	STACK_OF(X509) *certs = NULL;
	Settings::KeyPair kp;
	int ret = 0;

	mem = BIO_new_mem_buf(data.data(), data.size());
	Q_UNUSED(BIO_set_close(mem, BIO_NOCLOSE));
	pkcs = d2i_PKCS12_bio(mem, NULL);
	if (pkcs) {
		ret = PKCS12_parse(pkcs, NULL, &pkey, &x509, &certs);
		if (pkcs && !pkey && !x509 && ! pw.isEmpty()) {
			if (certs) {
				if (ret)
					sk_X509_free(certs);
				certs = NULL;
			}
			ret = PKCS12_parse(pkcs, pw.toUtf8().constData(), &pkey, &x509, &certs);
		}
		if (pkey && x509 && X509_check_private_key(x509, pkey)) {
			unsigned char *dptr;
			QByteArray key, crt;

			key.resize(i2d_PrivateKey(pkey, NULL));
			dptr=reinterpret_cast<unsigned char *>(key.data());
			i2d_PrivateKey(pkey, &dptr);

			crt.resize(i2d_X509(x509, NULL));
			dptr=reinterpret_cast<unsigned char *>(crt.data());
			i2d_X509(x509, &dptr);

			QSslCertificate qscCert = QSslCertificate(crt, QSsl::Der);
			QSslKey qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der);

			QList<QSslCertificate> qlCerts;
			qlCerts << qscCert;

			if (certs) {
				for (int i=0;i<sk_X509_num(certs);++i) {
					X509 *c = sk_X509_value(certs, i);

					crt.resize(i2d_X509(c, NULL));
					dptr=reinterpret_cast<unsigned char *>(crt.data());
					i2d_X509(c, &dptr);

					QSslCertificate cert = QSslCertificate(crt, QSsl::Der);
					qlCerts << cert;
				}
			}
			bool valid = ! qskKey.isNull();
			foreach(const QSslCertificate &cert, qlCerts)
				valid = valid && ! cert.isNull();
			if (valid)
				kp = Settings::KeyPair(qlCerts, qskKey);
		}
	}
Example #3
0
static int
_parcPkcs12KeyStore_ParseFile(PARCPkcs12KeyStore *keystore, const char *filename, const char *password)
{
    parcSecurity_AssertIsInitialized();

    FILE *fp = fopen(filename, "rb");

    assertNotNull(fp, "Error opening %s: %s", filename, strerror(errno));
    if (fp == NULL) {
        return -1;
    }

    PKCS12 *p12Keystore = NULL;
    d2i_PKCS12_fp(fp, &p12Keystore);
    fclose(fp);

    int success = PKCS12_parse(p12Keystore, password, &keystore->private_key, &keystore->x509_cert, NULL);
    PKCS12_free(p12Keystore);

    if (!success) {
        unsigned long errcode;
        while ((errcode = ERR_get_error()) != 0) {
            fprintf(stderr, "openssl error: %s\n", ERR_error_string(errcode, NULL));
        }
        return -1;
    }

    keystore->public_key = X509_get_pubkey(keystore->x509_cert);
    return 0;
}
void PEM_From_P12(PA_PluginParameters params)
{
	sLONG_PTR *pResult = (sLONG_PTR *)params->fResult;
	PackagePtr pParams = (PackagePtr)params->fParameters;
	
	C_BLOB Param1;
	C_BLOB Param2;
	C_TEXT Param3;
	C_TEXT returnValue;
	
	Param1.fromParamAtIndex(pParams, 1);
	Param3.fromParamAtIndex(pParams, 3);	
	
	BIO *bio = BIO_new_mem_buf((void *)Param1.getBytesPtr(), Param1.getBytesLength());

	if(bio){
		
		PKCS12 *p12 = d2i_PKCS12_bio(bio, NULL);
		
		if(p12){
			
			EVP_PKEY *key = NULL;
			X509 *cert = NULL;
			STACK_OF(X509) *ca = NULL;
            
			CUTF8String pass;
			Param3.copyUTF8String(&pass);
			
			if(PKCS12_parse(p12, (const char *)pass.c_str(), &key, &cert, &ca)){
				
				BIO *pem = BIO_new(BIO_s_mem());
				
				if(pem){
					
					PEM_write_bio_PrivateKey(pem, key, NULL, NULL, NULL, NULL, (void *)pass.c_str());
					
					char *buf = NULL;
					
					int len = BIO_get_mem_data(pem, &buf);
					
					if(len){
						Param2.setBytes((const uint8_t *)buf, len);
						Param2.toParamAtIndex(pParams, 2);
						CUTF8String pemStr = CUTF8String((const uint8_t *)buf, len);
						returnValue.setUTF8String(&pemStr);
					}
					
					BIO_free(pem);
					
				}
			}
		}
		
		BIO_free(bio);
		
	}	
	
	Param2.toParamAtIndex(pParams, 2);
	returnValue.setReturn(pResult);
}
Example #5
0
		bool Engine::set_p12_certificate_privatekey(const Data & data, const std::string & password)
		{
			if( data.empty() ) // BIO undefined behaviour when writing 0
				return false;
			BIO *mem = BIO_new(BIO_s_mem());
			BIO_write(mem, data.getData(), data.getSize());
			PKCS12 * pkcs12 = d2i_PKCS12_bio(mem, NULL);
			BIO_free(mem);
			mem = 0;
			X509 * cax = 0;
			EVP_PKEY * pkey = 0;
//			int succ = 
			PKCS12_parse(pkcs12, password.c_str(), &pkey, &cax, NULL);
//			int err = ERR_get_error();
//			const char * err_str = ERR_error_string(err, 0);
			int cert_res = SSL_use_certificate(ssl, cax);
			if (cax)
				X509_free(cax);
			cax = 0;
			int key_res = SSL_use_PrivateKey(ssl, pkey);
			if( pkey )
				EVP_PKEY_free(pkey);
			pkey = 0;
			int check_res = SSL_check_private_key(ssl);
			return cert_res == 1 && key_res == 1 && check_res == 1;
		}
Example #6
0
pki_pkcs12::pki_pkcs12(const QString fname, pem_password_cb *cb)
	:pki_base(fname)
{
	FILE *fp;
	char pass[MAX_PASS_LENGTH];
	EVP_PKEY *mykey = NULL;
	X509 *mycert = NULL;
	key=NULL; cert=NULL;
	passcb = cb;
	class_name="pki_pkcs12";
	certstack = sk_X509_new_null();
	pass_info p(XCA_TITLE, tr("Please enter the password to decrypt the PKCS#12 file.")
		+ "\n'" + fname + "'");
	fp = fopen(QString2filename(fname), "rb");
	if (fp) {
		PKCS12 *pkcs12 = d2i_PKCS12_fp(fp, NULL);
		fclose(fp);
		if (ign_openssl_error()) {
			if (pkcs12)
				PKCS12_free(pkcs12);
			throw errorEx(tr("Unable to load the PKCS#12 (pfx) file %1.").arg(fname));
		}
		if (PKCS12_verify_mac(pkcs12, "", 0) || PKCS12_verify_mac(pkcs12, NULL, 0))
			pass[0] = '\0';
		else if (passcb(pass, MAX_PASS_LENGTH, 0, &p) < 0) {
			/* cancel pressed */
			PKCS12_free(pkcs12);
			throw errorEx("","");
		}
		PKCS12_parse(pkcs12, pass, &mykey, &mycert, &certstack);
		int error = ERR_peek_error();
		if (ERR_GET_REASON(error) == PKCS12_R_MAC_VERIFY_FAILURE) {
			ign_openssl_error();
			PKCS12_free(pkcs12);
			throw errorEx(getClassName(), tr("The supplied password was wrong (%1)").arg(ERR_reason_error_string(error)));
		}
		ign_openssl_error();
		if (mycert) {
			if (mycert->aux && mycert->aux->alias) {
				alias = asn1ToQString(mycert->aux->alias);
				alias = QString::fromUtf8(alias.toAscii());
			}
			cert = new pki_x509(mycert);
			if (alias.isEmpty()) {
				cert->autoIntName();
			} else {
				cert->setIntName(alias);
			}
			alias = cert->getIntName();
		}
		if (mykey) {
			key = new pki_evp(mykey);
			key->setIntName(alias + "_key");
			key->bogusEncryptKey();
		}
		PKCS12_free(pkcs12);
	} else
		fopen_error(fname);
}
Example #7
0
int
useCertFile(SSL_CTX* ctx, const char* path, const char* passphrase, const char* cacertfile)
{
    FILE *p12_file;
    PKCS12 *p12_cert = NULL;
    EVP_PKEY *pkey;
    X509 *x509_cert;
    
    p12_file = fopen(path, "r");
    if (!p12_file)
    {
        timestamp_f(stderr);
        perror(path);
        return -1;
    }

    d2i_PKCS12_fp(p12_file, &p12_cert);
    fclose(p12_file);

    if (!PKCS12_parse(p12_cert, passphrase, &pkey, &x509_cert, NULL))
    {
        int error = ERR_get_error();
        timestamp_f(stderr);
        fprintf(stderr, "failed to parse p12 file; error %d\n", error);
        PKCS12_free(p12_cert);
        return -1;
    }
    PKCS12_free(p12_cert);

    if (!SSL_CTX_use_certificate(ctx, x509_cert))
    {
        int error = ERR_get_error();
        timestamp_f(stderr);
        fprintf(stderr, "failed to set cert for SSL context; error %d\n", error);
        X509_free(x509_cert);
        EVP_PKEY_free(pkey);
        return -1;
    }
    X509_free(x509_cert);

    if (!SSL_CTX_use_PrivateKey(ctx, pkey))
    {
        int error = ERR_get_error();
        timestamp_f(stderr);
        fprintf(stderr, "failed to set private key for SSL context; error %d\n", error);
        EVP_PKEY_free(pkey);
        return -1;
    }
    EVP_PKEY_free(pkey);

    if (cacertfile && *cacertfile && !SSL_CTX_load_verify_locations(ctx, cacertfile, NULL))
    {
        timestamp_f(stderr);
        fprintf(stderr, "failed to load root cert for verification from %s\n", cacertfile);
        return -1;
    }

    return 0;
}
Example #8
0
void SafetPKCS12Private::init( const QByteArray &data, const QByteArray &pin )
{
    OpenSSL_add_all_algorithms();

    qDebug("... SafetPKCS12Private::init ... 1");
    BIO *bio = BIO_new_mem_buf( const_cast<char*>(data.constData()), data.size() );
    if( !bio ){
        return setLastError();
        /*
        qDebug("!bio");
        qDebug(qPrintable(errorString));
        SafetYAWL::streamlog << SafetLog::Error << QObject::tr("Error al inicializar objeto PKCS12: BIO no valida");
        return;
        */
    }

    PKCS12 *p12 = d2i_PKCS12_bio( bio, NULL );
    BIO_free( bio );
    if( !p12 ){
        return setLastError();
        /*
        qDebug("!p12");
        qDebug(qPrintable(errorString));
        SafetYAWL::streamlog <<  SafetLog::Debug << errorString;
        SafetYAWL::streamlog << SafetLog::Error << QObject::tr("Error al inicializar objeto PKCS12: PKCS12 no valida");
        return;
        */
    }

    X509 *c = NULL;
    EVP_PKEY *k = NULL;
    int ret = PKCS12_parse( p12, pin.constData(), &k, &c, NULL );
    PKCS12_free( p12 );
    if( !ret ){
        return setLastError();
        /*
        setLastError();
        qDebug("!ret");
        qDebug(qPrintable(errorString));
        SafetYAWL::streamlog << SafetLog::Error << QObject::tr("Error al inicializar objeto PKCS12: EVP_PKEY no valida");
        return;
        */
    }
    SafetYAWL::streamlog <<  SafetLog::Debug << QObject::tr("Analizada correctamente la estructura PKCS12");

    cert = SafetPKCS12::fromX509( c );
    key = SafetPKCS12::keyFromEVP( k );

    X509_free( c );
    EVP_PKEY_free( k );
    qDebug("... SafetPKCS12Private::init ... 2");
    SafetYAWL::streamlog << SafetLog::Action << QObject::tr("Inicializado objeto SafetPKCS12 correctamente!");
}
Example #9
0
int __fastcall util_from_p12(char* data, int datalen, char* password, struct util_cert* cert)
{
	int r = 0;
	PKCS12 *p12 = NULL;
	if (data == NULL || datalen ==0) return 0;
	cert->x509 = NULL;
	cert->pkey = NULL;
	p12 = d2i_PKCS12(&p12, (const unsigned char**)&data, datalen);
	r = PKCS12_parse(p12, password, &(cert->pkey), &(cert->x509), NULL);
	PKCS12_free(p12);
	return r;
}
int sign_with_rsa_sha256(const char *input, const char *private_key, unsigned char *buffer_out, int *buffer_out_len) {

  FILE *fp;
  EVP_PKEY *pkey = 0;
  EVP_MD_CTX *ctx = 0;
  const EVP_MD *sha256_md = 0;
  unsigned int s = 0;
  PKCS12 *p12 = 0;
  X509 *cert = 0;

  OpenSSL_add_all_ciphers();
  OpenSSL_add_all_digests();
  OpenSSL_add_all_algorithms();
  ERR_load_crypto_strings();

  ctx = EVP_MD_CTX_create();
  EVP_MD_CTX_init(ctx);
  sha256_md = EVP_sha256(); 

  EVP_SignInit(ctx, sha256_md);
  EVP_SignUpdate(ctx, input, strlen(input));

  ERR_load_crypto_strings();
  if (!(fp = fopen(private_key, "rb"))) {
    perror("Error opening file with private key");
    return -1;
  }
  
  p12 = d2i_PKCS12_fp(fp, NULL);
  fclose (fp);
  if (!p12) {
    perror("Error reading PKCS#12 file");
    return -1;
  }

  if (!PKCS12_parse(p12, "notasecret", &pkey, &cert, NULL)) {
    perror("Error parsing PKCS#12 file");
    return -1;
  }

  s = EVP_PKEY_size(pkey);
  EVP_SignFinal(ctx, buffer_out, &s, pkey);
  
  *buffer_out_len = s;

  PKCS12_free(p12);
  EVP_MD_CTX_destroy(ctx);
  X509_free(cert);
  EVP_cleanup();

  return 0;
}
Example #11
0
int main(int argc, char **argv)
{
	FILE *fp;
	EVP_PKEY *pkey;
	X509 *cert;
	STACK_OF(X509) *ca = NULL;
	PKCS12 *p12;
	int i;
	if (argc != 4) {
		fprintf(stderr, "Usage: pkread p12file password opfile\n");
		exit (1);
	}
	SSLeay_add_all_algorithms();
	ERR_load_crypto_strings();
	if (!(fp = fopen(argv[1], "rb"))) {
		fprintf(stderr, "Error opening file %s\n", argv[1]);
		exit(1);
	}
	p12 = d2i_PKCS12_fp(fp, NULL);
	fclose (fp);
	if (!p12) {
		fprintf(stderr, "Error reading PKCS#12 file\n");
		ERR_print_errors_fp(stderr);
		exit (1);
	}
	if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) {
		fprintf(stderr, "Error parsing PKCS#12 file\n");
		ERR_print_errors_fp(stderr);
		exit (1);
	}
	PKCS12_free(p12);
	if (!(fp = fopen(argv[3], "w"))) {
		fprintf(stderr, "Error opening file %s\n", argv[1]);
		exit(1);
	}
	if (pkey) {
		fprintf(fp, "***Private Key***\n");
		PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
	}
	if (cert) {
		fprintf(fp, "***User Certificate***\n");
		PEM_write_X509_AUX(fp, cert);
	}
	if (ca && sk_X509_num(ca)) {
		fprintf(fp, "***Other Certificates***\n");
		for (i = 0; i < sk_X509_num(ca); i++) 
		    PEM_write_X509_AUX(fp, sk_X509_value(ca, i));
	}
	fclose(fp);
	return 0;
}
Example #12
0
SEXP loadPKCS12(SEXP privateKey) {
  EVP_PKEY *key;
  BIO *bio_mem;
  PKCS12 *p12;
  X509 *cert;
  
  if (TYPEOF(privateKey) != RAWSXP)
    Rf_error("PKCS12 private key must be a raw vector");

  bio_mem = BIO_new_mem_buf((void *) RAW(privateKey), LENGTH(privateKey));
  p12 = d2i_PKCS12_bio(bio_mem, &p12);
  if (!p12
    || !PKCS12_verify_mac(p12, pass, strlen(pass))
    || !PKCS12_parse(p12, pass, &key, &cert, NULL)
    || !key) {
    Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
  }
  return wrap_EVP_PKEY(key);
}
Example #13
0
static LUA_FUNCTION(openssl_pkcs12_read)
{
  PKCS12 * p12 = NULL;
  EVP_PKEY * pkey = NULL;
  X509 * cert = NULL;
  STACK_OF(X509) * ca = NULL;
  int ret = 0;

  int base64 = 0;
  int olb64 = 0;
  BIO * b64 = NULL;

  BIO * bio_in = load_bio_object(L, 1);
  const char *pass = luaL_checkstring(L, 2);
  if (!lua_isnoneornil(L, 3))
    base64 = auxiliar_checkboolean(L, 3);
  if (!lua_isnoneornil(L, 4))
    olb64 = auxiliar_checkboolean(L, 4);

  if (base64)
  {
    if ((b64 = BIO_new(BIO_f_base64())) == NULL)
      return 0;
    if (olb64) BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
    bio_in = BIO_push(b64, bio_in);
  }

  if (d2i_PKCS12_bio(bio_in, &p12) && PKCS12_parse(p12, pass, &pkey, &cert, &ca))
  {
    lua_newtable(L);

    AUXILIAR_SETOBJECT(L, cert, "openssl.x509" , -1, "cert");
    AUXILIAR_SETOBJECT(L, pkey, "openssl.evp_pkey" , -1, "pkey");
    AUXILIAR_SETOBJECT(L, ca, "openssl.stack_of_x509" , -1, "extracerts");

    ret = 1;
  }
  if (b64)
    BIO_free(b64);
  BIO_free(bio_in);
  PKCS12_free(p12);
  return ret;
}
Example #14
0
/*
 * call-seq:
 *    PKCS12.new -> pkcs12
 *    PKCS12.new(str) -> pkcs12
 *    PKCS12.new(str, pass) -> pkcs12
 *
 * === Parameters
 * * +str+ - Must be a DER encoded PKCS12 string.
 * * +pass+ - string
 */
static VALUE
ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
{
    BIO *in;
    VALUE arg, pass, pkey, cert, ca;
    char *passphrase;
    EVP_PKEY *key;
    X509 *x509;
    STACK_OF(X509) *x509s = NULL;
    int st = 0;
    PKCS12 *pkcs = DATA_PTR(self);

    if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self;
    passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
    in = ossl_obj2bio(arg);
    d2i_PKCS12_bio(in, &pkcs);
    DATA_PTR(self) = pkcs;
    BIO_free(in);

    pkey = cert = ca = Qnil;
    if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s))
	ossl_raise(ePKCS12Error, "PKCS12_parse");
    pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key,
		      &st); /* NO DUP */
    if(st) goto err;
    cert = rb_protect((VALUE(*)_((VALUE)))ossl_x509_new, (VALUE)x509, &st);
    if(st) goto err;
    if(x509s){
	ca =
	    rb_protect((VALUE(*)_((VALUE)))ossl_x509_sk2ary, (VALUE)x509s, &st);
	if(st) goto err;
    }

  err:
    X509_free(x509);
    sk_X509_pop_free(x509s, X509_free);
    ossl_pkcs12_set_key(self, pkey);
    ossl_pkcs12_set_cert(self, cert);
    ossl_pkcs12_set_ca_certs(self, ca);
    if(st) rb_jump_tag(st);

    return self;
}
Example #15
0
static int loadPkcs12( const char *fn, const char* pw)
{
    /* you are lost in a maze of twisty crypto algorithms... */
    PKCS12 *p12;
    X509 *x509;
    EVP_PKEY *pkey;
    FILE *fp;
    int ret;
    fp = fopen(fn, "r");
    if (fp == NULL) {
        printf("Could not open file `%s\n", fn);
        return -1;
    }

    p12 = d2i_PKCS12_fp(fp, NULL);

    fclose(fp);

    if (p12 == NULL) {
        printf("Could not read certificate from file `%s\n",fn);
        return -1;
    }

    /* we need some more for the P12 decoding */
    OpenSSL_add_all_ciphers();
    OpenSSL_add_all_digests();
    ERR_load_crypto_strings();

    ret = PKCS12_parse(p12, getenv(pw),&pkey, &x509, NULL);
    saveCertificateHome(x509, true);
    savePKeyHome( x509, pkey);
    PKCS12_free(p12);

    if (ret != 1) {
        printf("Error parsing certificate (incorrect password?): %s\n", 
                ERR_reason_error_string(ERR_get_error()));
        return -1;
    }
    return 0;
}
Example #16
0
void Pkcs12::parse(string password) throw(Pkcs12Exception)
{
	EVP_PKEY* pkey = NULL;
	X509* cert = NULL;
	STACK_OF(X509)* ca = NULL;
	unsigned long opensslError = 0;
	X509* tmp = NULL;
	
	//Limpa fila de erros e carrega tabelas
	ERR_clear_error();	
	//OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();
	
	if(!PKCS12_parse(this->pkcs12, password.c_str(), &pkey, &cert, &ca))
	{
		opensslError = ERR_get_error();
		
		switch(ERR_GET_REASON(opensslError))
		{
			case PKCS12_R_MAC_VERIFY_FAILURE :
				throw Pkcs12Exception(Pkcs12Exception::PARSE_ERROR, "Pkcs12::parse");
				break;
				
			case PKCS12_R_PARSE_ERROR :
				throw Pkcs12Exception(Pkcs12Exception::MAC_VERIFY_FAILURE, "Pkcs12::parse");
				break;
		}
	}
	
	this->privKey = new PrivateKey(pkey);
	this->cert = new Certificate(cert);
			
	for(int i = 0 ; i < sk_X509_num(ca) ; i ++)
	{
		tmp = sk_X509_value(ca, i);
		this->ca.push_back(new Certificate(tmp));
	}
	
	sk_X509_free(ca);
}
Example #17
0
bool OpenSSLContext::setClientCertificate(CertificateWithKey::ref certificate) {
	boost::shared_ptr<PKCS12Certificate> pkcs12Certificate = boost::dynamic_pointer_cast<PKCS12Certificate>(certificate);
	if (!pkcs12Certificate || pkcs12Certificate->isNull()) {
		return false;
	}

	// Create a PKCS12 structure
	BIO* bio = BIO_new(BIO_s_mem());
	BIO_write(bio, vecptr(pkcs12Certificate->getData()), pkcs12Certificate->getData().size());
	boost::shared_ptr<PKCS12> pkcs12(d2i_PKCS12_bio(bio, NULL), PKCS12_free);
	BIO_free(bio);
	if (!pkcs12) {
		return false;
	}

	// Parse PKCS12
	X509 *certPtr = 0;
	EVP_PKEY* privateKeyPtr = 0;
	STACK_OF(X509)* caCertsPtr = 0;
	int result = PKCS12_parse(pkcs12.get(), reinterpret_cast<const char*>(vecptr(pkcs12Certificate->getPassword())), &privateKeyPtr, &certPtr, &caCertsPtr);
	if (result != 1) { 
		return false;
	}
	boost::shared_ptr<X509> cert(certPtr, X509_free);
	boost::shared_ptr<EVP_PKEY> privateKey(privateKeyPtr, EVP_PKEY_free);
	boost::shared_ptr<STACK_OF(X509)> caCerts(caCertsPtr, freeX509Stack);

	// Use the key & certificates
	if (SSL_CTX_use_certificate(context_, cert.get()) != 1) {
		return false;
	}
	if (SSL_CTX_use_PrivateKey(context_, privateKey.get()) != 1) {
		return false;
	}
	for (int i = 0;  i < sk_X509_num(caCerts.get()); ++i) {
		SSL_CTX_add_extra_chain_cert(context_, sk_X509_value(caCerts.get(), i));
	}
	return true;
}
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;
}
Example #19
0
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size, 
    const char *cert_pwd, uint8_t **signature, int32_t *signature_size)
{
    PKCS12 *p12 = NULL;
    EVP_PKEY *evp_pkey = NULL;
    BUF_MEM *buf_mem = NULL;
    BIO *cert_bio = NULL;
    BIO *message_bio = NULL;
    BIO *signature_bio = NULL;
    CMS_ContentInfo *cms = NULL;
    CMS_SignerInfo *signer_info = NULL;
    STACK_OF(X509) *ca_stack = NULL;
    X509 *cert = NULL;
    int32_t result = 0;
    int32_t err = MZ_OK;


    if (message == NULL || cert_data == NULL || signature == NULL || signature_size == NULL)
        return MZ_PARAM_ERROR;

    mz_crypt_init();

    *signature = NULL;
    *signature_size = 0;

    cert_bio = BIO_new_mem_buf(cert_data, cert_data_size);

    if (d2i_PKCS12_bio(cert_bio, &p12) == NULL)
        err = MZ_SIGN_ERROR;
    if (err == MZ_OK)
        result = PKCS12_parse(p12, cert_pwd, &evp_pkey, &cert, &ca_stack);
    if (result)
    {
        cms = CMS_sign(NULL, NULL, ca_stack, NULL, CMS_BINARY | CMS_PARTIAL);
        if (cms)
            signer_info = CMS_add1_signer(cms, cert, evp_pkey, EVP_sha256(), 0);
        if (signer_info == NULL)
        {
            err = MZ_SIGN_ERROR;
        }
        else
        {
            message_bio = BIO_new_mem_buf(message, message_size);
            signature_bio = BIO_new(BIO_s_mem());

            result = CMS_final(cms, message_bio, NULL, CMS_BINARY);
            if (result)
                result = i2d_CMS_bio(signature_bio, cms);
            if (result)
            {
                BIO_flush(signature_bio);
                BIO_get_mem_ptr(signature_bio, &buf_mem);

                *signature_size = buf_mem->length;
                *signature = MZ_ALLOC(buf_mem->length);
                
                memcpy(*signature, buf_mem->data, buf_mem->length);
            }
#if 0            
            BIO *yy = BIO_new_file("xyz", "wb");
            BIO_write(yy, *signature, *signature_size);
            BIO_flush(yy);
            BIO_free(yy);
#endif
        }
    }

    if (!result)
        err = MZ_SIGN_ERROR;

    if (cms)
        CMS_ContentInfo_free(cms);
    if (signature_bio)
        BIO_free(signature_bio);
    if (cert_bio)
        BIO_free(cert_bio);
    if (message_bio)
        BIO_free(message_bio);
    if (p12)
        PKCS12_free(p12);

    if (err != MZ_OK && *signature != NULL)
    {
        MZ_FREE(*signature);
        *signature = NULL;
        *signature_size = 0;
    }

    return err;
}
Example #20
0
static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12)
{
	EVP_PKEY *pkey = NULL;
	X509 *cert = NULL;
	STACK_OF(X509) *ca;
	int ret = 0;
	char *pass;

	pass = vpninfo->cert_password;
	vpninfo->cert_password = NULL;
 retrypass:
	/* We do this every time round the loop, to work around a bug in
	   OpenSSL < 1.0.0-beta2 -- where the stack at *ca will be freed
	   when PKCS12_parse() returns an error, but *ca is left pointing
	   to the freed memory. */
	ca = NULL;
	if (!pass && request_passphrase(vpninfo, "openconnect_pkcs12", &pass,
					_("Enter PKCS#12 pass phrase:")) < 0) {
		PKCS12_free(p12);
		return -EINVAL;
	}
	if (!PKCS12_parse(p12, pass, &pkey, &cert, &ca)) {
		unsigned long err = ERR_peek_error();

		openconnect_report_ssl_errors(vpninfo);

		if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 &&
		    ERR_GET_FUNC(err) == PKCS12_F_PKCS12_PARSE &&
		    ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Parse PKCS#12 failed (wrong passphrase?)\n"));
			free(pass);
			pass = NULL;
			goto retrypass;
		}

		vpn_progress(vpninfo, PRG_ERR,
			     _("Parse PKCS#12 failed (see above errors)\n"));
		PKCS12_free(p12);
		free(pass);
		return -EINVAL;
	}
	free(pass);
	if (cert) {
		char buf[200];
		vpninfo->cert_x509 = cert;
		SSL_CTX_use_certificate(vpninfo->https_ctx, cert);
		X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
		vpn_progress(vpninfo, PRG_INFO,
			     _("Using client certificate '%s'\n"), buf);
	} else {
		vpn_progress(vpninfo, PRG_ERR,
			     _("PKCS#12 contained no certificate!"));
		ret = -EINVAL;
	}

	if (pkey) {
		SSL_CTX_use_PrivateKey(vpninfo->https_ctx, pkey);
		EVP_PKEY_free(pkey);
	} else {
		vpn_progress(vpninfo, PRG_ERR,
			     _("PKCS#12 contained no private key!"));
		ret = -EINVAL;
	}

	/* Only include supporting certificates which are actually necessary */
	if (ca) {
		int i;
	next:
		for (i = 0; i < sk_X509_num(ca); i++) {
			X509 *cert2 = sk_X509_value(ca, i);
			if (X509_check_issued(cert2, cert) == X509_V_OK) {
				char buf[200];

				if (cert2 == cert)
					break;
				if (X509_check_issued(cert2, cert2) == X509_V_OK)
					break;

				X509_NAME_oneline(X509_get_subject_name(cert2),
						  buf, sizeof(buf));
				vpn_progress(vpninfo, PRG_DEBUG,
					     _("Extra cert from PKCS#12: '%s'\n"), buf);
				CRYPTO_add(&cert2->references, 1, CRYPTO_LOCK_X509);
				SSL_CTX_add_extra_chain_cert(vpninfo->https_ctx, cert2);
				cert = cert2;
				goto next;
			}
		}
		sk_X509_pop_free(ca, X509_free);
	}

	PKCS12_free(p12);
	return ret;
}
Example #21
0
int main(int argc, char **argv)
{

    BIO* in=NULL;
    BIO* out=NULL;

    char * outfile = NULL;
    char * infile = NULL ;

    int tabLength=100;
    char *binaryptr;
    char* mimetype;
    char* mimetypeaccept=NULL;
    char* contenttype;
    const char** pp;
    unsigned char* hostporturl = NULL;
    BIO * p12bio ;
    char **args = argv + 1;
    unsigned char * serverurl;
    sslctxparm p;
    char *response;

    CURLcode res;
    struct curl_slist * headers=NULL;
    int badarg=0;

    binaryptr = malloc(tabLength);

    p.verbose = 0;
    p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE);

    curl_global_init(CURL_GLOBAL_DEFAULT);

    /* we need some more for the P12 decoding */

    OpenSSL_add_all_ciphers();
    OpenSSL_add_all_digests();
    ERR_load_crypto_strings();



    while (*args && *args[0] == '-')
    {
        if (!strcmp (*args, "-in"))
        {
            if (args[1])
            {
                infile=*(++args);
            }
            else badarg=1;
        }
        else if (!strcmp (*args, "-out"))
        {
            if (args[1])
            {
                outfile=*(++args);
            }
            else badarg=1;
        }
        else if (!strcmp (*args, "-p12"))
        {
            if (args[1])
            {
                p.p12file = *(++args);
            }
            else badarg=1;
        }
        else if (strcmp(*args,"-envpass") == 0)
        {
            if (args[1])
            {
                p.pst = getenv(*(++args));
            }
            else badarg=1;
        }
        else if (strcmp(*args,"-connect") == 0)
        {
            if (args[1])
            {
                hostporturl = *(++args);
            }
            else badarg=1;
        }
        else if (strcmp(*args,"-mimetype") == 0)
        {
            if (args[1])
            {
                mimetype = *(++args);
            }
            else badarg=1;
        }
        else if (strcmp(*args,"-acceptmime") == 0)
        {
            if (args[1])
            {
                mimetypeaccept = *(++args);
            }
            else badarg=1;
        }
        else if (strcmp(*args,"-accesstype") == 0)
        {
            if (args[1])
            {
                if ((p.accesstype = OBJ_obj2nid(OBJ_txt2obj(*++args,0))) == 0) badarg=1;
            }
            else badarg=1;
        }
        else if (strcmp(*args,"-verbose") == 0)
        {
            p.verbose++;
        }
        else badarg=1;
        args++;
    }

    if (mimetype==NULL || mimetypeaccept == NULL) badarg = 1;

    if (badarg)
    {
        for (pp=curlx_usage; (*pp != NULL); pp++)
            BIO_printf(p.errorbio,"%s\n",*pp);
        BIO_printf(p.errorbio,"\n");
        goto err;
    }



    /* set input */

    if ((in=BIO_new(BIO_s_file())) == NULL)
    {
        BIO_printf(p.errorbio, "Error setting input bio\n");
        goto err;
    }
    else if (infile == NULL)
        BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
    else if (BIO_read_filename(in,infile) <= 0)
    {
        BIO_printf(p.errorbio, "Error opening input file %s\n", infile);
        BIO_free(in);
        goto err;
    }

    /* set output  */

    if ((out=BIO_new(BIO_s_file())) == NULL)
    {
        BIO_printf(p.errorbio, "Error setting output bio.\n");
        goto err;
    }
    else if (outfile == NULL)
        BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
    else if (BIO_write_filename(out,outfile) <= 0)
    {
        BIO_printf(p.errorbio, "Error opening output file %s\n", outfile);
        BIO_free(out);
        goto err;
    }


    p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE);

    if (!(p.curl = curl_easy_init()))
    {
        BIO_printf(p.errorbio, "Cannot init curl lib\n");
        goto err;
    }



    if (!(p12bio = BIO_new_file(p.p12file , "rb")))
    {
        BIO_printf(p.errorbio, "Error opening P12 file %s\n", p.p12file);
        goto err;
    }
    if (!(p.p12 = d2i_PKCS12_bio (p12bio, NULL)))
    {
        BIO_printf(p.errorbio, "Cannot decode P12 structure %s\n", p.p12file);
        goto err;
    }

    p.ca= NULL;
    if (!(PKCS12_parse (p.p12, p.pst, &(p.pkey), &(p.usercert), &(p.ca) ) ))
    {
        BIO_printf(p.errorbio,"Invalid P12 structure in %s\n", p.p12file);
        goto err;
    }

    if (sk_X509_num(p.ca) <= 0)
    {
        BIO_printf(p.errorbio,"No trustworthy CA given.%s\n", p.p12file);
        goto err;
    }

    if (p.verbose > 1)
        X509_print_ex(p.errorbio,p.usercert,0,0);

    /* determine URL to go */

    if (hostporturl)
    {
        serverurl = malloc(9+strlen(hostporturl));
        sprintf(serverurl,"https://%s",hostporturl);
    }
    else if (p.accesstype != 0)   /* see whether we can find an AIA or SIA for a given access type */
    {
        if (!(serverurl = my_get_ext(p.usercert,p.accesstype,NID_info_access)))
        {
            int j=0;
            BIO_printf(p.errorbio,"no service URL in user cert "
                       "cherching in others certificats\n");
            for (j=0; j<sk_X509_num(p.ca); j++)
            {
                if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype,
                                            NID_info_access)))
                    break;
                if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype,
                                            NID_sinfo_access)))
                    break;
            }
        }
    }

    if (!serverurl)
    {
        BIO_printf(p.errorbio, "no service URL in certificats,"
                   " check '-accesstype (AD_DVCS | ad_timestamping)'"
                   " or use '-connect'\n");
        goto err;
    }

    if (p.verbose)
        BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl);

    curl_easy_setopt(p.curl, CURLOPT_URL, serverurl);

    /* Now specify the POST binary data */

    curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr);
    curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,(long)tabLength);

    /* pass our list of custom made headers */

    contenttype = malloc(15+strlen(mimetype));
    sprintf(contenttype,"Content-type: %s",mimetype);
    headers = curl_slist_append(headers,contenttype);
    curl_easy_setopt(p.curl, CURLOPT_HTTPHEADER, headers);

    if (p.verbose)
        BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl);

    {
        FILE *outfp;
        BIO_get_fp(out,&outfp);
        curl_easy_setopt(p.curl, CURLOPT_WRITEDATA, outfp);
    }

    res = curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun)  ;

    if (res != CURLE_OK)
        BIO_printf(p.errorbio,"%d %s=%d %d\n", __LINE__, "CURLOPT_SSL_CTX_FUNCTION",CURLOPT_SSL_CTX_FUNCTION,res);

    curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_DATA, &p);

    {
        int lu;
        int i=0;
        while ((lu = BIO_read (in,&binaryptr[i],tabLength-i)) >0 )
        {
            i+=lu;
            if (i== tabLength)
            {
                tabLength+=100;
                binaryptr=realloc(binaryptr,tabLength); /* should be more careful */
            }
        }
        tabLength = i;
    }
    /* Now specify the POST binary data */

    curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr);
    curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,(long)tabLength);


    /* Perform the request, res will get the return code */

    BIO_printf(p.errorbio,"%d %s %d\n", __LINE__, "curl_easy_perform",
               res = curl_easy_perform(p.curl));
    {
        int result =curl_easy_getinfo(p.curl,CURLINFO_CONTENT_TYPE,&response);
        if( mimetypeaccept && p.verbose)
            if(!strcmp(mimetypeaccept,response))
                BIO_printf(p.errorbio,"the response has a correct mimetype : %s\n",
                           response);
            else
                BIO_printf(p.errorbio,"the reponse doesn\'t has an acceptable "
                           "mime type, it is %s instead of %s\n",
                           response,mimetypeaccept);
    }

    /*** code d'erreur si accept mime ***, egalement code return HTTP != 200 ***/

    /* free the header list*/

    curl_slist_free_all(headers);

    /* always cleanup */
    curl_easy_cleanup(p.curl);

    BIO_free(in);
    BIO_free(out);
    return (EXIT_SUCCESS);

err:
    BIO_printf(p.errorbio,"error");
    exit(1);
}
Example #22
0
DVT_STATUS CERTIFICATE_FILE_CLASS::importPkcs12(const char* filename, bool certificatesOnly,
												 const char* password)

//  DESCRIPTION     : Import certificates from a PKCS#12 formated file.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           : Returns MSG_OK, MSG_ERROR, MSG_FILE_NOT_EXIST, MSG_NO_VALUE, MSG_INVALID_PASSWORD
//<<===========================================================================
{
	DVT_STATUS status = MSG_ERROR;
	BIO* bio_ptr = NULL;
	PKCS12 *p12_ptr = NULL;
	EVP_PKEY *pkey_ptr = NULL;
	X509 *cert_ptr = NULL;
	STACK_OF(X509) *ca_ptr = NULL;
	const char* password_ptr = NULL;
	int count = 0;


	// clear the error queue
	ERR_clear_error();

	// open the file
	bio_ptr = BIO_new(BIO_s_file_internal());
	if (bio_ptr == NULL)
	{
		openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "setting up to read PKCS#12 file");
		status = MSG_ERROR;
		goto end;
	}
	if (BIO_read_filename(bio_ptr, filename) <= 0)
	{
		unsigned long err;
		err = ERR_peek_error();
		if ((ERR_GET_LIB(err) == ERR_LIB_SYS) && (ERR_GET_REASON(err) == ERROR_FILE_NOT_FOUND))
		{
			// file does not exist
			ERR_clear_error(); // eat any errors
			status = MSG_FILE_NOT_EXIST;
		}
		else
		{
			openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "opening PKCS#12 file for reading");
			status = MSG_ERROR;
		}
		goto end;
	}

	// read the file
	p12_ptr = d2i_PKCS12_bio(bio_ptr, NULL);
	if (!p12_ptr) 
	{
		openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "reading PKCS#12 file");
		status = MSG_ERROR;
		goto end;
	}

	// see if we have a password that will work
	if (PKCS12_verify_mac(p12_ptr, NULL, 0))
	{
		password_ptr = NULL;
	}
	else if(PKCS12_verify_mac(p12_ptr, "", 0))
	{
		password_ptr = "";
	}
	else if(PKCS12_verify_mac(p12_ptr, password, strlen(password)))
	{
		password_ptr = password;
	}
	else
	{
		status = MSG_INVALID_PASSWORD;
		goto end;
	}

	// parse the data
	if (!PKCS12_parse(p12_ptr, password_ptr, &pkey_ptr, &cert_ptr, &ca_ptr)) 
	{
		openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "parsing PKCS#12 file");
		status = MSG_ERROR;
		ca_ptr = NULL; // this is freed by PKCS12_parse(), but not set to NULL
		goto end;
	}

	if ((pkey_ptr != NULL) && !certificatesOnly) 
	{
		// save the private key
		if (!push(pkey_ptr))
		{
			status = MSG_ERROR;
			goto end;
		}
		count++;
	}

	if (cert_ptr != NULL) 
	{
		// save the certificate
		if (!push(cert_ptr))
		{
			status = MSG_ERROR;
			goto end;
		}
		count++;
	}

	if ((ca_ptr != NULL) && (sk_X509_num(ca_ptr) > 0))
	{
		X509* x509_ptr;

		// save each of the certificates
		while ((x509_ptr = sk_X509_shift(ca_ptr)) != NULL)
		{
			if (!push(x509_ptr))
			{
				status = MSG_ERROR;
				goto end;
			}
			count++;
		}
	}

	if (count == 0)
	{
		status = MSG_NO_VALUE;
	}
	else
	{
		status = MSG_OK;
	}

end:
	if (bio_ptr != NULL) BIO_free(bio_ptr);
	if (p12_ptr != NULL) PKCS12_free(p12_ptr);
	if (pkey_ptr != NULL) EVP_PKEY_free(pkey_ptr);
	if (cert_ptr != NULL) X509_free(cert_ptr);
	if (ca_ptr != NULL) sk_X509_pop_free(ca_ptr, X509_free);

	return status;
}
Example #23
0
/*
 * PKCS#12 decoder.  It operates by decoding all of the blob content,
 * extracting all the interesting data from it and storing them internally,
 * then serving them one piece at a time.
 */
static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name,
                                          const char *pem_header,
                                          const unsigned char *blob,
                                          size_t len, void **pctx,
                                          int *matchcount,
                                          const UI_METHOD *ui_method,
                                          void *ui_data)
{
    OSSL_STORE_INFO *store_info = NULL;
    STACK_OF(OSSL_STORE_INFO) *ctx = *pctx;

    if (ctx == NULL) {
        /* Initial parsing */
        PKCS12 *p12;
        int ok = 0;

        if (pem_name != NULL)
            /* No match, there is no PEM PKCS12 tag */
            return NULL;

        if ((p12 = d2i_PKCS12(NULL, &blob, len)) != NULL) {
            char *pass = NULL;
            char tpass[PEM_BUFSIZE];
            EVP_PKEY *pkey = NULL;
            X509 *cert = NULL;
            STACK_OF(X509) *chain = NULL;

            *matchcount = 1;

            if (PKCS12_verify_mac(p12, "", 0)
                || PKCS12_verify_mac(p12, NULL, 0)) {
                pass = "";
            } else {
                if ((pass = file_get_pass(ui_method, tpass, PEM_BUFSIZE,
                                          "PKCS12 import password",
                                          ui_data)) == NULL) {
                    OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS12,
                                  OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR);
                    goto p12_end;
                }
                if (!PKCS12_verify_mac(p12, pass, strlen(pass))) {
                    OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS12,
                                  OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC);
                    goto p12_end;
                }
            }

            if (PKCS12_parse(p12, pass, &pkey, &cert, &chain)) {
                OSSL_STORE_INFO *osi_pkey = NULL;
                OSSL_STORE_INFO *osi_cert = NULL;
                OSSL_STORE_INFO *osi_ca = NULL;

                if ((ctx = sk_OSSL_STORE_INFO_new_null()) != NULL
                    && (osi_pkey = OSSL_STORE_INFO_new_PKEY(pkey)) != NULL
                    && sk_OSSL_STORE_INFO_push(ctx, osi_pkey) != 0
                    && (osi_cert = OSSL_STORE_INFO_new_CERT(cert)) != NULL
                    && sk_OSSL_STORE_INFO_push(ctx, osi_cert) != 0) {
                    ok = 1;
                    osi_pkey = NULL;
                    osi_cert = NULL;

                    while(sk_X509_num(chain) > 0) {
                        X509 *ca = sk_X509_value(chain, 0);

                        if ((osi_ca = OSSL_STORE_INFO_new_CERT(ca)) == NULL
                            || sk_OSSL_STORE_INFO_push(ctx, osi_ca) == 0) {
                            ok = 0;
                            break;
                        }
                        osi_ca = NULL;
                        (void)sk_X509_shift(chain);
                    }
                }
                if (!ok) {
                    OSSL_STORE_INFO_free(osi_ca);
                    OSSL_STORE_INFO_free(osi_cert);
                    OSSL_STORE_INFO_free(osi_pkey);
                    sk_OSSL_STORE_INFO_pop_free(ctx, OSSL_STORE_INFO_free);
                    EVP_PKEY_free(pkey);
                    X509_free(cert);
                    sk_X509_pop_free(chain, X509_free);
                    ctx = NULL;
                }
                *pctx = ctx;
            }
        }
     p12_end:
        PKCS12_free(p12);
        if (!ok)
            return NULL;
    }

    if (ctx != NULL) {
        *matchcount = 1;
        store_info = sk_OSSL_STORE_INFO_shift(ctx);
    }

    return store_info;
}
Example #24
0
int
tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
    const char *pkcs12_file_inline,
    bool load_ca_file
    )
{
  FILE *fp;
  EVP_PKEY *pkey;
  X509 *cert;
  STACK_OF(X509) *ca = NULL;
  PKCS12 *p12;
  int i;
  char password[256];

  ASSERT(NULL != ctx);

  if (!strcmp (pkcs12_file, INLINE_FILE_TAG) && pkcs12_file_inline)
    {
      BIO *b64 = BIO_new(BIO_f_base64());
      BIO *bio = BIO_new_mem_buf((void *) pkcs12_file_inline,
	  (int) strlen(pkcs12_file_inline));
      ASSERT(b64 && bio);
      BIO_push(b64, bio);
      p12 = d2i_PKCS12_bio(b64, NULL);
      if (!p12)
	msg(M_SSLERR, "Error reading inline PKCS#12 file");
      BIO_free(b64);
      BIO_free(bio);
    }
  else
    {
      /* Load the PKCS #12 file */
      if (!(fp = platform_fopen(pkcs12_file, "rb")))
	msg(M_SSLERR, "Error opening file %s", pkcs12_file);
      p12 = d2i_PKCS12_fp(fp, NULL);
      fclose(fp);
      if (!p12)
	msg(M_SSLERR, "Error reading PKCS#12 file %s", pkcs12_file);
    }

  /* Parse the PKCS #12 file */
  if (!PKCS12_parse(p12, "", &pkey, &cert, &ca))
   {
     pem_password_callback (password, sizeof(password) - 1, 0, NULL);
     /* Reparse the PKCS #12 file with password */
     ca = NULL;
     if (!PKCS12_parse(p12, password, &pkey, &cert, &ca))
      {
#ifdef ENABLE_MANAGEMENT
	      if (management && (ERR_GET_REASON (ERR_peek_error()) == PKCS12_R_MAC_VERIFY_FAILURE))
		management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL);
#endif
	PKCS12_free(p12);
	return 1;
      }
   }
  PKCS12_free(p12);

  /* Load Certificate */
  if (!SSL_CTX_use_certificate (ctx->ctx, cert))
   msg (M_SSLERR, "Cannot use certificate");

  /* Load Private Key */
  if (!SSL_CTX_use_PrivateKey (ctx->ctx, pkey))
   msg (M_SSLERR, "Cannot use private key");
  warn_if_group_others_accessible (pkcs12_file);

  /* Check Private Key */
  if (!SSL_CTX_check_private_key (ctx->ctx))
   msg (M_SSLERR, "Private key does not match the certificate");

  /* Set Certificate Verification chain */
  if (load_ca_file)
   {
     if (ca && sk_X509_num(ca))
      {
	for (i = 0; i < sk_X509_num(ca); i++)
	  {
	      if (!X509_STORE_add_cert(ctx->ctx->cert_store,sk_X509_value(ca, i)))
	      msg (M_SSLERR, "Cannot add certificate to certificate chain (X509_STORE_add_cert)");
	    if (!SSL_CTX_add_client_CA(ctx->ctx, sk_X509_value(ca, i)))
	      msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)");
	  }
      }
   }
  return 0;
}
Example #25
0
/* ChangePasswordPKCS12() returns:
 * -1 Wrong password
 * 0  Changing password failed for unknown reason
 * 1  Password changed successfully
 */
int ChangePasswordPKCS12(HWND hwndDlg)
{
  char keyfile[MAX_PATH];
  char oldpsw[50];
  char newpsw[50];
  WCHAR oldpsw_unicode[50];
  WCHAR newpsw_unicode[50];
  FILE *fp;

  EVP_PKEY *privkey;
  X509 *cert;
  STACK_OF(X509) *ca = NULL;
  PKCS12 *p12;
  PKCS12 *new_p12;
  char *alias;

  /* Get filename, old_psw and new_psw from Dialog */
  GetDlgItemText(hwndDlg, TEXT_KEYFILE, keyfile, sizeof(keyfile) - 1); 
  GetDlgItemTextW(hwndDlg, EDIT_PSW_CURRENT, oldpsw_unicode, sizeof(oldpsw_unicode)/2 - 1); 
  GetDlgItemTextW(hwndDlg, EDIT_PSW_NEW, newpsw_unicode, sizeof(newpsw_unicode)/2 - 1); 

  /* Convert Unicode to ASCII (CP850) */
  ConvertUnicode2Ascii(oldpsw_unicode, oldpsw, sizeof(oldpsw));
  if (!ConvertUnicode2Ascii(newpsw_unicode, newpsw, sizeof(newpsw)))
    {
      ShowLocalizedMsg(GUI_NAME, ERR_INVALID_CHARS_IN_PSW, "");
      return(-1);
    }

  /* Load the PKCS #12 file */
  if (!(fp = fopen(keyfile, "rb")))
    {
      /* error opening file */
      ShowLocalizedMsg(GUI_NAME, ERR_OPEN_PRIVATE_KEY_FILE, keyfile);
      return(0);
    }
  p12 = d2i_PKCS12_fp(fp, NULL);
  fclose (fp);
  if (!p12) 
    {
      /* error reading PKCS #12 */
      ShowLocalizedMsg(GUI_NAME, ERR_READ_PKCS12, keyfile);
      return(0);
    }

  /* Parse the PKCS #12 file */
  if (!PKCS12_parse(p12, oldpsw, &privkey, &cert, &ca))
    {
      /* old password incorrect */
      ShowLocalizedMsg(GUI_NAME, ERR_OLD_PWD_INCORRECT, ""); 
      PKCS12_free(p12);
      return(-1);
    }

  /* Free old PKCS12 object */
  PKCS12_free(p12);

  /* Get FriendlyName of old cert */
  alias = X509_alias_get0(cert, NULL);

  /* Create new PKCS12 object */
  p12 = PKCS12_create(newpsw, alias, privkey, cert, ca, 0,0,0,0,0);
  if (!p12)
    {
      /* create failed */
      //ShowMsg(GUI_NAME, ERR_error_string(ERR_peek_last_error(), NULL));
      ShowLocalizedMsg(GUI_NAME, ERR_CREATE_PKCS12, "");
      return(0);
    }

  /* Free old key, cert and ca */
  EVP_PKEY_free(privkey);
  X509_free(cert);
  sk_X509_pop_free(ca, X509_free);

  /* Open keyfile for writing */
  if (!(fp = fopen(keyfile, "wb")))
    {
      ShowLocalizedMsg(GUI_NAME, ERR_OPEN_WRITE_KEY, keyfile);
      PKCS12_free(p12);
      return(0);
    }

  /* Write new key to file */
  i2d_PKCS12_fp(fp, p12);

  PKCS12_free(p12);
  fclose(fp);
  /* signal success to user */
  ShowLocalizedMsg(GUI_NAME, INFO_PWD_CHANGED, "");

  return(1);
}
Example #26
0
static
int cert_stuff(struct connectdata *conn,
               SSL_CTX* ctx,
               char *cert_file,
               const char *cert_type,
               char *key_file,
               const char *key_type)
{
  struct SessionHandle *data = conn->data;
  int file_type;

  if(cert_file != NULL) {
    SSL *ssl;
    X509 *x509;
    int cert_done = 0;

    if(data->set.key_passwd) {
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
      /*
       * If password has been given, we store that in the global
       * area (*shudder*) for a while:
       */
      size_t len = strlen(data->set.key_passwd);
      if(len < sizeof(global_passwd))
        memcpy(global_passwd, data->set.key_passwd, len+1);
#else
      /*
       * We set the password in the callback userdata
       */
      SSL_CTX_set_default_passwd_cb_userdata(ctx,
                                             data->set.key_passwd);
#endif
      /* Set passwd callback: */
      SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
    }

    file_type = do_file_type(cert_type);

#define SSL_CLIENT_CERT_ERR \
    "unable to use client certificate (no key found or wrong pass phrase?)"

    switch(file_type) {
    case SSL_FILETYPE_PEM:
      /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
      if(SSL_CTX_use_certificate_chain_file(ctx,
                                            cert_file) != 1) {
        failf(data, SSL_CLIENT_CERT_ERR);
        return 0;
      }
      break;

    case SSL_FILETYPE_ASN1:
      /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
         we use the case above for PEM so this can only be performed with
         ASN1 files. */
      if(SSL_CTX_use_certificate_file(ctx,
                                      cert_file,
                                      file_type) != 1) {
        failf(data, SSL_CLIENT_CERT_ERR);
        return 0;
      }
      break;
    case SSL_FILETYPE_ENGINE:
      failf(data, "file type ENG for certificate not implemented");
      return 0;

    case SSL_FILETYPE_PKCS12:
    {
#ifdef HAVE_PKCS12_SUPPORT
      FILE *f;
      PKCS12 *p12;
      EVP_PKEY *pri;

      f = fopen(cert_file,"rb");
      if (!f) {
        failf(data, "could not open PKCS12 file '%s'", cert_file);
        return 0;
      }
      p12 = d2i_PKCS12_fp(f, NULL);
      fclose(f);

      PKCS12_PBE_add();

      if (!PKCS12_parse(p12, data->set.key_passwd, &pri, &x509, NULL)) {
        failf(data,
              "could not parse PKCS12 file, check password, OpenSSL error %s",
              ERR_error_string(ERR_get_error(), NULL) );
        return 0;
      }

      PKCS12_free(p12);

      if(SSL_CTX_use_certificate(ctx, x509) != 1) {
        failf(data, SSL_CLIENT_CERT_ERR);
        EVP_PKEY_free(pri);
        X509_free(x509);
        return 0;
      }

      if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) {
        failf(data, "unable to use private key from PKCS12 file '%s'",
              cert_file);
        EVP_PKEY_free(pri);
        X509_free(x509);
        return 0;
      }

      EVP_PKEY_free(pri);
      X509_free(x509);
      cert_done = 1;
      break;
#else
      failf(data, "file type P12 for certificate not supported");
      return 0;
#endif
    }
    default:
      failf(data, "not supported file type '%s' for certificate", cert_type);
      return 0;
    }

    file_type = do_file_type(key_type);

    switch(file_type) {
    case SSL_FILETYPE_PEM:
      if(cert_done)
        break;
      if(key_file == NULL)
        /* cert & key can only be in PEM case in the same file */
        key_file=cert_file;
    case SSL_FILETYPE_ASN1:
      if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
        failf(data, "unable to set private key file: '%s' type %s\n",
              key_file, key_type?key_type:"PEM");
        return 0;
      }
      break;
    case SSL_FILETYPE_ENGINE:
#ifdef HAVE_OPENSSL_ENGINE_H
      {                         /* XXXX still needs some work */
        EVP_PKEY *priv_key = NULL;
        if(conn && conn->data && conn->data->state.engine) {
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
          UI_METHOD *ui_method = UI_OpenSSL();
#endif
          if(!key_file || !key_file[0]) {
            failf(data, "no key set to load from crypto engine\n");
            return 0;
          }
          /* the typecast below was added to please mingw32 */
          priv_key = (EVP_PKEY *)
            ENGINE_load_private_key(conn->data->state.engine,key_file,
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
                                    ui_method,
#endif
                                    data->set.key_passwd);
          if(!priv_key) {
            failf(data, "failed to load private key from crypto engine\n");
            return 0;
          }
          if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
            failf(data, "unable to set private key\n");
            EVP_PKEY_free(priv_key);
            return 0;
          }
          EVP_PKEY_free(priv_key);  /* we don't need the handle any more... */
        }
        else {
          failf(data, "crypto engine not set, can't load private key\n");
          return 0;
        }
      }
      break;
#else
      failf(data, "file type ENG for private key not supported\n");
      return 0;
#endif
    case SSL_FILETYPE_PKCS12:
      if(!cert_done) {
        failf(data, "file type P12 for private key not supported\n");
        return 0;
      }
      break;
    default:
      failf(data, "not supported file type for private key\n");
      return 0;
    }

    ssl=SSL_new(ctx);
    if (NULL == ssl) {
      failf(data,"unable to create an SSL structure\n");
      return 0;
    }

    x509=SSL_get_certificate(ssl);

    /* This version was provided by Evan Jordan and is supposed to not
       leak memory as the previous version: */
    if(x509 != NULL) {
      EVP_PKEY *pktmp = X509_get_pubkey(x509);
      EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl));
      EVP_PKEY_free(pktmp);
    }

    SSL_free(ssl);

    /* If we are using DSA, we can copy the parameters from
     * the private key */


    /* Now we know that a key and cert have been set against
     * the SSL context */
    if(!SSL_CTX_check_private_key(ctx)) {
      failf(data, "Private key does not match the certificate public key");
      return(0);
    }
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
    /* erase it now */
    memset(global_passwd, 0, sizeof(global_passwd));
#endif
  }
  return(1);
}
Example #27
0
/*
 * Constructor for PKCS12 objects, never called by Python code directly.
 * The strategy for this object is to create all the Python objects
 * corresponding to the cert/key/CA certs right away
 *
 * Arguments: p12        - A "real" PKCS12 object or NULL
 *            passphrase - Passphrase to use when decrypting the PKCS12 object
 * Returns:   The newly created PKCS12 object
 */
crypto_PKCS12Obj *
crypto_PKCS12_New(PKCS12 *p12, char *passphrase) {
    crypto_PKCS12Obj *self = NULL;
    PyObject *cacertobj = NULL;

    unsigned char *alias_str;
    int alias_len;

    X509 *cert = NULL;
    EVP_PKEY *pkey = NULL;
    STACK_OF(X509) *cacerts = NULL;

    int i, cacert_count = 0;

    /* allocate space for the CA cert stack */
    if((cacerts = sk_X509_new_null()) == NULL) {
        goto error;   /* out of memory? */
    }

    /* parse the PKCS12 lump */
    if (p12) {
        if (!PKCS12_parse(p12, passphrase, &pkey, &cert, &cacerts)) {
	    /*
             * If PKCS12_parse fails, and it allocated cacerts, it seems to
             * free cacerts, but not re-NULL the pointer.  Zounds!  Make sure
             * it is re-set to NULL here, else we'll have a double-free below.
             */
            cacerts = NULL;
            exception_from_error_queue(crypto_Error);
            goto error;
        } else {
	  /*
	   * OpenSSL 1.0.0 sometimes leaves an X509_check_private_key error in
	   * the queue for no particular reason.  This error isn't interesting
	   * to anyone outside this function.  It's not even interesting to
	   * us.  Get rid of it.
	   */
	  flush_error_queue();
	}
    }

    if (!(self = PyObject_GC_New(crypto_PKCS12Obj, &crypto_PKCS12_Type))) {
        goto error;
    }

    /* client certificate and friendlyName */
    if (cert == NULL) {
        Py_INCREF(Py_None);
        self->cert = Py_None;
        Py_INCREF(Py_None);
        self->friendlyname = Py_None;
    } else {
        if ((self->cert = (PyObject *)crypto_X509_New(cert, 1)) == NULL) {
            goto error;
        }

        /*  Now we need to extract the friendlyName of the PKCS12
         *  that was stored by PKCS_parse() in the alias of the
         *  certificate. */
        alias_str = X509_alias_get0(cert, &alias_len);
        if (alias_str) {
            self->friendlyname = Py_BuildValue(BYTESTRING_FMT "#", alias_str, alias_len);
            if (!self->friendlyname) {
                /*
                 * XXX Untested
                 */
                goto error;
            }
            /* success */
        } else {
            Py_INCREF(Py_None);
            self->friendlyname = Py_None;
        }
    }

    /* private key */
    if (pkey == NULL) {
        Py_INCREF(Py_None);
        self->key = Py_None;
    } else {
        if ((self->key = (PyObject *)crypto_PKey_New(pkey, 1)) == NULL)
            goto error;
    }

    /* CA certs */
    cacert_count = sk_X509_num(cacerts);
    if (cacert_count <= 0) {
        Py_INCREF(Py_None);
        self->cacerts = Py_None;
    } else {
        if ((self->cacerts = PyTuple_New(cacert_count)) == NULL) {
            goto error;
        }

        for (i = 0; i < cacert_count; i++) {
            cert = sk_X509_value(cacerts, i);
            if ((cacertobj = (PyObject *)crypto_X509_New(cert, 1)) == NULL) {
                goto error;
            }
            PyTuple_SET_ITEM(self->cacerts, i, cacertobj);
        }
    }

    sk_X509_free(cacerts); /* Don't free the certs, just the container. */
    PyObject_GC_Track(self);

    return self;

error:
    sk_X509_free(cacerts); /* NULL safe. Free just the container. */
    if (self) {
        crypto_PKCS12_clear(self);
        PyObject_GC_Del(self);
    }
    return NULL;
}
X509* ssl_parse_certificate(void* pCert, size_t certLen, LPCSTR pwd, EVP_PKEY** privateKey)
{
    X509 *x=NULL;
    PKCS12* p12 = NULL;

    if(privateKey != NULL)
    {
        *privateKey = NULL;
    }
    
    //check for PEM BASE64 header
    BIO *certBio = NULL;
    if ((certBio=BIO_new(BIO_s_mem())) != NULL)
    {
        BIO_write(certBio, (const char*)pCert, certLen);
    
        x = PEM_read_bio_X509(certBio, NULL, 0, NULL);
        
        if(x != NULL)
        {
            BIO_reset(certBio);
            BIO_write(certBio, (const char*)pCert, certLen);

            if(privateKey != NULL)
            {
                *privateKey = PEM_read_bio_PrivateKey(certBio, NULL, password_cb, (void*)pwd);
            }
        }
    
        if(x == NULL)
        {
            BIO_reset(certBio);
            BIO_write(certBio, (const char*)pCert, certLen);
    
            p12 = d2i_PKCS12_bio(certBio, NULL);
    
            if(p12 != NULL)
            {
                if(privateKey == NULL)
                {
                    PKCS12_parse(p12, pwd, NULL, &x, NULL); 
                }
                else
                {
                    PKCS12_parse(p12, pwd, privateKey, &x, NULL); 
                }
    
                PKCS12_free(p12);
            }
        }
    
        BIO_free(certBio);
    }
    
    if(x == NULL)
    {
        const UINT8* tmp = (const UINT8*)pCert;
        
        x = d2i_X509(NULL, &tmp, certLen);

        if(x != NULL && privateKey != NULL)
        {
            X509_PKEY* pKey;
            
            tmp = (const UINT8*)pCert;
            
            pKey = d2i_X509_PKEY(NULL, &tmp, certLen);            

            if(pKey != NULL)
            {
                *privateKey = pKey->dec_pkey;
            }
        }
    }
    
    return x;
    
}
/*============================================================================
 * OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile(
    OpcUa_StringA           a_privateKeyFile,
    OpcUa_P_FileFormat      a_fileFormat,
    OpcUa_StringA           a_password,         /* optional: just needed encrypted PEM */
    OpcUa_ByteString*       a_pPrivateKey)
{
    BIO*            pPrivateKeyFile     = OpcUa_Null;
    RSA*            pRsaPrivateKey      = OpcUa_Null;
    EVP_PKEY*       pEvpKey             = OpcUa_Null;
    unsigned char*  pData;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_LoadPrivateKeyFromFile");

    /* check parameters */
    OpcUa_ReturnErrorIfArgumentNull(a_privateKeyFile);
    OpcUa_ReturnErrorIfArgumentNull(a_pPrivateKey);

    if(a_fileFormat == OpcUa_Crypto_Encoding_Invalid)
    {
        return OpcUa_BadInvalidArgument;
    }

    OpcUa_ReferenceParameter(a_password);

    /* open file */
    pPrivateKeyFile = BIO_new_file((const char*)a_privateKeyFile, "rb");
    OpcUa_ReturnErrorIfArgumentNull(pPrivateKeyFile);

    /* read and convert file */
    switch(a_fileFormat)
    {
    case OpcUa_Crypto_Encoding_PEM:
        {
            /* read from file */
            pEvpKey = PEM_read_bio_PrivateKey(  pPrivateKeyFile,    /* file                 */
                                                NULL,               /* key struct           */
                                                0,                  /* password callback    */
                                                a_password);        /* default passphrase or arbitrary handle */
            OpcUa_GotoErrorIfNull(pEvpKey, OpcUa_Bad);
            break;
        }
    case OpcUa_Crypto_Encoding_PKCS12:
        {
            int iResult = 0;

            /* read from file. */
            PKCS12* pPkcs12 = d2i_PKCS12_bio(pPrivateKeyFile, NULL);

            if (pPkcs12 == 0)
            {
                OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError);
            }

            /*  parse the certificate. */
            iResult = PKCS12_parse(pPkcs12, a_password, &pEvpKey, NULL, NULL);

            if (iResult == 0)
            {
                OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError);
            }

            /*  free certificate. */
            PKCS12_free(pPkcs12);
            pPkcs12 = NULL;
            break;
        }
    case OpcUa_Crypto_Encoding_DER:
    default:
        {
            uStatus = OpcUa_BadNotSupported;
            OpcUa_GotoError;
        }
    }

    /* convert to intermediary openssl struct */
    pRsaPrivateKey = EVP_PKEY_get1_RSA(pEvpKey);
    EVP_PKEY_free(pEvpKey);
    OpcUa_GotoErrorIfNull(pRsaPrivateKey, OpcUa_Bad);

    /* get required length */
    a_pPrivateKey->Length = i2d_RSAPrivateKey(pRsaPrivateKey, OpcUa_Null);
    OpcUa_GotoErrorIfTrue((a_pPrivateKey->Length <= 0), OpcUa_Bad);

    /* allocate target buffer */
    a_pPrivateKey->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pPrivateKey->Length);
    OpcUa_GotoErrorIfAllocFailed(a_pPrivateKey->Data);

    /* do real conversion */
    pData = a_pPrivateKey->Data;
    a_pPrivateKey->Length = i2d_RSAPrivateKey(pRsaPrivateKey, &pData);
    OpcUa_GotoErrorIfTrue((a_pPrivateKey->Length <= 0), OpcUa_Bad);

    RSA_free(pRsaPrivateKey);
    BIO_free(pPrivateKeyFile);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pEvpKey)
    {
        EVP_PKEY_free(pEvpKey);
    }

    if(a_pPrivateKey != OpcUa_Null)
    {
        if(a_pPrivateKey->Data != OpcUa_Null)
        {
            OpcUa_P_Memory_Free(a_pPrivateKey->Data);
            a_pPrivateKey->Data = OpcUa_Null;
            a_pPrivateKey->Length = -1;
        }
    }

    if(pPrivateKeyFile != NULL)
    {
        BIO_free(pPrivateKeyFile);
    }

    if(pRsaPrivateKey != NULL)
    {
        RSA_free(pRsaPrivateKey);
    }

OpcUa_FinishErrorHandling;
}
Example #30
0
static int ssl_need_client_cert(SSL *ssl, X509 **cert, EVP_PKEY **pkey)
{
    serf_ssl_context_t *ctx = SSL_get_app_data(ssl);
    apr_status_t status;

    if (ctx->cached_cert) {
        *cert = ctx->cached_cert;
        *pkey = ctx->cached_cert_pw;
        return 1;
    }

    while (ctx->cert_callback) {
        const char *cert_path;
        apr_file_t *cert_file;
        BIO *bio;
        PKCS12 *p12;
        int i;
        int retrying_success = 0;

        if (ctx->cert_file_success) {
            status = APR_SUCCESS;
            cert_path = ctx->cert_file_success;
            ctx->cert_file_success = NULL;
            retrying_success = 1;
        } else {
            status = ctx->cert_callback(ctx->cert_userdata, &cert_path);
        }

        if (status || !cert_path) {
          break;
        }

        /* Load the x.509 cert file stored in PKCS12 */
        status = apr_file_open(&cert_file, cert_path, APR_READ, APR_OS_DEFAULT,
                               ctx->pool);

        if (status) {
            continue;
        }

        bio = BIO_new(&bio_file_method);
        bio->ptr = cert_file;

        ctx->cert_path = cert_path;
        p12 = d2i_PKCS12_bio(bio, NULL);
        apr_file_close(cert_file);

        i = PKCS12_parse(p12, NULL, pkey, cert, NULL);

        if (i == 1) {
            PKCS12_free(p12);
            ctx->cached_cert = *cert;
            ctx->cached_cert_pw = *pkey;
            if (!retrying_success && ctx->cert_cache_pool) {
                const char *c;

                c = apr_pstrdup(ctx->cert_cache_pool, ctx->cert_path);

                apr_pool_userdata_setn(c, "serf:ssl:cert",
                                       apr_pool_cleanup_null,
                                       ctx->cert_cache_pool);
            }
            return 1;
        }
        else {
            int err = ERR_get_error();
            ERR_clear_error();
            if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 &&
                ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) {
                if (ctx->cert_pw_callback) {
                    const char *password;

                    if (ctx->cert_pw_success) {
                        status = APR_SUCCESS;
                        password = ctx->cert_pw_success;
                        ctx->cert_pw_success = NULL;
                    } else {
                        status = ctx->cert_pw_callback(ctx->cert_pw_userdata,
                                                       ctx->cert_path,
                                                       &password);
                    }

                    if (!status && password) {
                        i = PKCS12_parse(p12, password, pkey, cert, NULL);
                        if (i == 1) {
                            PKCS12_free(p12);
                            ctx->cached_cert = *cert;
                            ctx->cached_cert_pw = *pkey;
                            if (!retrying_success && ctx->cert_cache_pool) {
                                const char *c;

                                c = apr_pstrdup(ctx->cert_cache_pool,
                                                ctx->cert_path);

                                apr_pool_userdata_setn(c, "serf:ssl:cert",
                                                       apr_pool_cleanup_null,
                                                       ctx->cert_cache_pool);
                            }
                            if (!retrying_success && ctx->cert_pw_cache_pool) {
                                const char *c;

                                c = apr_pstrdup(ctx->cert_pw_cache_pool,
                                                password);

                                apr_pool_userdata_setn(c, "serf:ssl:certpw",
                                                       apr_pool_cleanup_null,
                                                       ctx->cert_pw_cache_pool);
                            }
                            return 1;
                        }
                    }
                }
                PKCS12_free(p12);
                return 0;
            }
            else {
                printf("OpenSSL cert error: %d %d %d\n", ERR_GET_LIB(err),
                       ERR_GET_FUNC(err),
                       ERR_GET_REASON(err));
                PKCS12_free(p12);
            }
        }
    }

    return 0;
}