Пример #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;
}
Пример #2
1
static void process_file(const char *filename)
{
	FILE *pfxfile;
	int i, count;
	unsigned char buffer[LINE_BUFFER_SIZE];
	BIO* in = NULL;
	PKCS12 *p12 = NULL;
	const char *ext[] = {".p12",".pfx"};
	char *fname;

	if (!(pfxfile = fopen(filename, "rb"))) {
	    fprintf(stderr, "! %s : %s\n", filename, strerror(errno));
	    return;
	}
	in = BIO_new_file(filename, "rb");
	if (!in) {
		fprintf (stderr, "PKCS12 file not found: %s\n", filename);
		fclose(pfxfile);
		return;
	}
	if(!(p12 = d2i_PKCS12_bio (in, NULL))) {
		perror("Unable to create PKCS12 object\n");
		fclose(pfxfile);
	    	return;
	}
	if(PKCS12_verify_mac(p12, "", -1)) {
		fprintf(stderr, "%s has no password!\n", filename);
		fclose(pfxfile);
		return;
	}
	count = fread(buffer, 1, LINE_BUFFER_SIZE, pfxfile);
	fname = strip_suffixes(basename(filename), ext, 2);
	printf("%s:$pfx$*%d*", fname, count);
	for (i = 0; i < count; i++) {
	    printf("%c%c", itoa16[ARCH_INDEX(buffer[i] >> 4)],
	            itoa16[ARCH_INDEX(buffer[i] & 0x0f)]);
	}
	printf("\n");
	fclose(pfxfile);
	if(in)
		BIO_free(in);
}
Пример #3
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);
}
Пример #4
0
void *work_brute( void *ptr ) {
	// Opening p12 file
	BIO* in = NULL;
	workerbrute *wthread = (workerbrute *) ptr;

	pthread_mutex_lock(wthread->m);

	in = BIO_new_file(wthread->file2crack, "rb");
	if (!in) {
		fprintf (stderr,"PKCS12 file not found: %s\n",wthread->file2crack);
		exit(10);
	}

	// Creating PKCS12 object
	PKCS12 *p12 = NULL;
	if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
		perror("Unable to create PKCS12 object\n");
		exit(30);
	}

	pthread_mutex_unlock(wthread->m);

	int maxwordlength = wthread->wordlength;
	int i;
	*(wthread->count) = 0;
	for (wthread->wordlength=wthread->wordlength_min; wthread->wordlength <= maxwordlength; wthread->wordlength++) {
		for (i=wthread->id; i<wthread->baselength; i+=nthreads) {
			wthread->word[0] = wthread->base[i];
			if (wthread->wordlength>1)
				generate(wthread, 1, p12, wthread->count);
			else
				try(wthread, p12, wthread->count);
		}
	}
}

void generate(workerbrute *wthread, int pivot, PKCS12 *p12, unsigned long long *gcount) {
	int i, j, ret;

	for (i=0; i<wthread->baselength; i++) {
		wthread->word[pivot] = wthread->base[i];
		if (pivot < wthread->wordlength-1)
			generate(wthread, pivot+1, p12, gcount);
		else
			try(wthread,p12,gcount);
	}
	wthread->word[pivot] = '\0';
}

void try(workerbrute *wthread, PKCS12 *p12, unsigned long long *gcount) {
	(*gcount)++;

	if (PKCS12_verify_mac(p12, wthread->word, -1)) {
		if (!wthread->quiet) sleep(ELAPSEDSECONDS);
		printf("\n**********************************************************\n");
		printf("Brute force attack - Thread %d - Password found: %s\n",wthread->id+1,wthread->word);
		printf("**********************************************************\n\n");
		exit(0);
	}
}
Пример #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;
		}
Пример #6
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);
		}
	}
Пример #7
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!");
}
Пример #8
0
void *work_dict( void *ptr ) {
	// Opening p12 file
	BIO* in = NULL;
	workerdict *wthread = (workerdict *) ptr;

	pthread_mutex_lock(wthread->m);

	in = BIO_new_file(wthread->file2crack, "rb");
	if (!in) {
		fprintf (stderr,"PKCS12 file not found: %s\n",wthread->file2crack);
		exit(10);
	}

	// Creating PKCS12 object
	PKCS12 *p12 = NULL;
	if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
		perror("Unable to create PKCS12 object\n");
		exit(30);
	}

	pthread_mutex_unlock(wthread->m);

	char line[256];
	char found = 0;
	char stop = 0;
	int i = 0;
	char *p;
	*(wthread->count) = 0;
	// Work
	while (!found && fgets(line, sizeof line,wthread->dictfile) != NULL) {
		p = line + strlen(line) - 1;
		if (*p == '\n') *p = '\0';
		if ((p != line) && (*--p == '\r')) *p = '\0';
		(*(wthread->count))++;
		if (PKCS12_verify_mac(p12, line, -1))
			found = 1;	
	}

	if (found) {
		if (!wthread->quiet) sleep(ELAPSEDSECONDS);
		printf("\n*********************************************************\n");
		printf("Dictionary attack - Thread %d - Password found: %s\n",wthread->id+1,line);
		printf("*********************************************************\n\n");
		exit(0);
	}

	pthread_exit(0);
}
Пример #9
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);
}
Пример #10
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;
}
Пример #11
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;
}
Пример #12
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;
}
Пример #13
0
static void *get_salt(char *ciphertext)
{
	char *decoded_data;
	int i;
	char *ctcopy = strdup(ciphertext);
	char *keeptr = ctcopy;
	char *p;
	static struct custom_salt cs;
	PKCS12 *p12 = NULL;
	BIO *bp;
	ctcopy += 6;	/* skip over "$pfx$*" */
	p = strtok(ctcopy, "*");
	cs.len = atoi(p);
	decoded_data = (char *) malloc(cs.len + 1);
	p = strtok(NULL, "*");
	for (i = 0; i < cs.len; i++)
		decoded_data[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16 +
    			atoi16[ARCH_INDEX(p[i * 2 + 1])];
	decoded_data[cs.len] = 0;
	/* load decoded data into OpenSSL structures */
	bp = BIO_new(BIO_s_mem());
	if (!bp) {
		fprintf(stderr, "OpenSSL BIO allocation failure\n");
		exit(-2);
	}
	BIO_write(bp, decoded_data, cs.len);
	if(!(p12 = d2i_PKCS12_bio(bp, NULL))) {
		perror("Unable to create PKCS12 object from bio\n");
		exit(-3);
	}
	/* save custom_salt information */
	memset(&cs, 0, sizeof(cs));
	memcpy(&cs.pfx, p12, sizeof(PKCS12));
	BIO_free(bp);
	MEM_FREE(decoded_data);
	MEM_FREE(keeptr);
	return (void *) &cs;
}
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;
}
Пример #15
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;
}
Пример #16
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);
}
Пример #17
0
/*============================================================================
 * OpcUa_P_OpenSSL_X509_LoadFromFile
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_X509_LoadFromFile(
    OpcUa_StringA               a_fileName,
    OpcUa_P_FileFormat          a_fileFormat,
    OpcUa_StringA               a_sPassword,        /* optional: just for OpcUa_PKCS12 */
    OpcUa_ByteString*           a_pCertificate)
{
    BIO*            pCertFile       = OpcUa_Null;
    X509*           pCertX509       = OpcUa_Null;
    PKCS12*         pPKCS12Cert     = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_LoadFromFile");

    /* check filename */
    if(OpcUa_P_String_strlen(a_fileName) < 1)
    {
        uStatus = OpcUa_BadInvalidArgument;
        OpcUa_GotoErrorIfBad(uStatus);
    }

    /* import certificate from file by the given encoding type */
    pCertFile = BIO_new_file((const char*)a_fileName, "r");
    OpcUa_ReturnErrorIfArgumentNull(pCertFile);

    switch(a_fileFormat)
    {
    case OpcUa_Crypto_Encoding_DER:
        {

            pCertX509 = d2i_X509_bio(pCertFile,      /* sourcefile */
                                     (X509**)NULL);  /* target (if preallocated) */
            break;
        }
    case OpcUa_Crypto_Encoding_PEM:
        {

            pCertX509 = PEM_read_bio_X509(  pCertFile,          /* sourcefile */
                                            (X509**)OpcUa_Null, /* target (if preallocated) */
                                            OpcUa_Null,         /* password callback function */
                                            OpcUa_Null);        /* passphrase or callback data */
            break;
        }
    case OpcUa_Crypto_Encoding_PKCS12:
        {
            d2i_PKCS12_bio(pCertFile, &pPKCS12Cert);

            PKCS12_parse(pPKCS12Cert, a_sPassword, OpcUa_Null, &pCertX509, OpcUa_Null);

            if(pPKCS12Cert != OpcUa_Null)
            {
                PKCS12_free(pPKCS12Cert);
                /*OPENSSL_free(pPKCS12Cert);*/
            }

            break;
        }
    default:
        {
            BIO_free(pCertFile);
            return OpcUa_BadNotSupported;
        }
    }

    BIO_free(pCertFile);
    pCertFile = OpcUa_Null;

    if(pCertX509 == OpcUa_Null)
    {
        /* error in OpenSSL - maybe certificate file was corrupt */
        return OpcUa_Bad;
    }

    /* prepare container */
    memset(a_pCertificate, 0, sizeof(OpcUa_ByteString));

    /* get required length for conversion target buffer */
    a_pCertificate->Length = i2d_X509(  pCertX509,
                                            NULL);

    if(a_pCertificate->Length <= 0)
    {
        /* conversion to DER not possible */
        uStatus = OpcUa_Bad;
    }

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

    /* convert into DER */
    a_pCertificate->Length = i2d_X509(  pCertX509,
                                            &(a_pCertificate->Data));
    if(a_pCertificate->Length <= 0)
    {
        /* conversion to DER not possible */
        uStatus = OpcUa_Bad;
    }
    else
    {
        /* correct pointer incrementation by i2d_X509() */
        a_pCertificate->Data -= a_pCertificate->Length;
    }

    X509_free(pCertX509);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pCertX509 != OpcUa_Null)
    {
        X509_free(pCertX509);
    }

    if(pPKCS12Cert != OpcUa_Null)
    {
        OPENSSL_free(pPKCS12Cert);
    }

    if(a_pCertificate->Data != OpcUa_Null)
    {
        OpcUa_P_Memory_Free(a_pCertificate->Data);
        a_pCertificate->Data = OpcUa_Null;
    }

    if(pCertFile != OpcUa_Null)
    {
        BIO_free(pCertFile);
    }

OpcUa_FinishErrorHandling;
}
Пример #18
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;
}
Пример #19
0
/*============================================================================
 * OpcUa_P_OpenSSL_X509_GetPrivateKey
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_X509_GetPrivateKey(
    OpcUa_CryptoProvider*       a_pProvider,
    OpcUa_StringA               a_certificateFileName,
    OpcUa_StringA               a_password,             /* this is optional */
    OpcUa_Key*                  a_pPrivateKey)
{
    BIO*            pCertFile       = OpcUa_Null;
    PKCS12*         pPKCS12Cert     = OpcUa_Null;
    EVP_PKEY*       pPrivateKey     = OpcUa_Null;
    RSA*            pRsaPrivateKey  = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_GetPrivateKey");

    OpcUa_ReferenceParameter(a_pProvider);

    OpcUa_ReturnErrorIfArgumentNull(a_pProvider);
    OpcUa_ReturnErrorIfArgumentNull(a_certificateFileName);
    OpcUa_ReturnErrorIfArgumentNull(a_pPrivateKey);

    /* import certificate from file by the given encoding type */
    pCertFile = BIO_new_file((const char*)a_certificateFileName, "r");
    OpcUa_ReturnErrorIfArgumentNull(pCertFile);

    /* convert certificate file handle to PKCS12 structure */
    d2i_PKCS12_bio(pCertFile, &pPKCS12Cert);

    /* close certificat file handle */
    BIO_free(pCertFile);

    if(pPKCS12Cert != OpcUa_Null)
    {
        /* get the private key from the PKCS12 structure*/
        PKCS12_parse(pPKCS12Cert, a_password, &pPrivateKey, OpcUa_Null, OpcUa_Null);
    }
    else
    {
        uStatus = OpcUa_Bad;
        OpcUa_ReturnStatusCode;
    }

    if(pPKCS12Cert != OpcUa_Null)
    {
        PKCS12_free(pPKCS12Cert);
        pPKCS12Cert = OpcUa_Null;
    }

    switch(EVP_PKEY_type(pPrivateKey->type))
    {
    case EVP_PKEY_RSA:
        {
            /* convert to intermediary openssl struct */
            pRsaPrivateKey = EVP_PKEY_get1_RSA(pPrivateKey);
            EVP_PKEY_free(pPrivateKey);
            OpcUa_GotoErrorIfNull(pRsaPrivateKey, OpcUa_Bad);

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

            if(a_pPrivateKey->Key.Data == OpcUa_Null)
            {
                OpcUa_ReturnStatusCode;
            }

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

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

            /* correct buffer pointer */
            a_pPrivateKey->Key.Data -= a_pPrivateKey->Key.Length;

            a_pPrivateKey->Type = OpcUa_Crypto_KeyType_Rsa_Private;

            break;
        }
    case EVP_PKEY_EC:
    case EVP_PKEY_DSA:
    case EVP_PKEY_DH:
    default:
        {
            uStatus =  OpcUa_BadNotSupported;
            OpcUa_GotoErrorIfBad(uStatus);
        }
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

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

    if(pPrivateKey != OpcUa_Null)
    {
        EVP_PKEY_free(pPrivateKey);
    }

OpcUa_FinishErrorHandling;
}
Пример #20
0
 *
 * \return Whether the PKCS12 structure was successfully loaded
 */
static bool load_pkcs12(BIO *bio_pkcs12, pem_password_cb *pem_cb, void *cb_data,
                        EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
{
    assert(bio_pkcs12 && pem_cb && pkey && cert);

    PKCS12 *p12;
    const char *pass;
    char buf[PEM_BUFSIZE];
    int len;
    int ret = 0;

    // Load PKCS12 from stream
    p12 = d2i_PKCS12_bio(bio_pkcs12, nullptr);
    if (!p12) {
        LOGE("Failed to load PKCS12 file");
        openssl_log_errors();
        goto finished;
    }

    // Try empty password
    if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, nullptr, 0)) {
        pass = "";
    } else {
        // Otherwise, get password from callback
        len = pem_cb(buf, PEM_BUFSIZE, 0, cb_data);
        if (len < 0) {
            LOGE("Passphrase callback failed");
            goto finished;
Пример #21
0
int MAIN(int argc, char **argv)
{
    ENGINE *e = NULL;
    char *infile=NULL, *outfile=NULL, *keyname = NULL;	
    char *certfile=NULL;
    BIO *in=NULL, *out = NULL;
    char **args;
    char *name = NULL;
    char *csp_name = NULL;
    PKCS12 *p12 = NULL;
    char pass[50], macpass[50];
    int export_cert = 0;
    int options = 0;
    int chain = 0;
    int badarg = 0;
    int iter = PKCS12_DEFAULT_ITER;
    int maciter = PKCS12_DEFAULT_ITER;
    int twopass = 0;
    int keytype = 0;
    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
    int ret = 1;
    int macver = 1;
    int noprompt = 0;
    STACK *canames = NULL;
    char *cpass = NULL, *mpass = NULL;
    char *passargin = NULL, *passargout = NULL, *passarg = NULL;
    char *passin = NULL, *passout = NULL;
    char *inrand = NULL;
    char *CApath = NULL, *CAfile = NULL;
    char *engine=NULL;

    apps_startup();

    enc = EVP_des_ede3_cbc();
    if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;

    args = argv + 1;


    while (*args) {
	if (*args[0] == '-') {
		if (!strcmp (*args, "-nokeys")) options |= NOKEYS;
		else if (!strcmp (*args, "-keyex")) keytype = KEY_EX;
		else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG;
		else if (!strcmp (*args, "-nocerts")) options |= NOCERTS;
		else if (!strcmp (*args, "-clcerts")) options |= CLCERTS;
		else if (!strcmp (*args, "-cacerts")) options |= CACERTS;
		else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS);
		else if (!strcmp (*args, "-info")) options |= INFO;
		else if (!strcmp (*args, "-chain")) chain = 1;
		else if (!strcmp (*args, "-twopass")) twopass = 1;
		else if (!strcmp (*args, "-nomacver")) macver = 0;
		else if (!strcmp (*args, "-descert"))
    			cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
		else if (!strcmp (*args, "-export")) export_cert = 1;
		else if (!strcmp (*args, "-des")) enc=EVP_des_cbc();
#ifndef OPENSSL_NO_IDEA
		else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc();
#endif
		else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
#ifndef OPENSSL_NO_AES
		else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc();
		else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc();
		else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc();
#endif
		else if (!strcmp (*args, "-noiter")) iter = 1;
		else if (!strcmp (*args, "-maciter"))
					 maciter = PKCS12_DEFAULT_ITER;
		else if (!strcmp (*args, "-nomaciter"))
					 maciter = 1;
		else if (!strcmp (*args, "-nodes")) enc=NULL;
		else if (!strcmp (*args, "-certpbe")) {
			if (args[1]) {
				args++;
				cert_pbe=OBJ_txt2nid(*args);
				if(cert_pbe == NID_undef) {
					BIO_printf(bio_err,
						 "Unknown PBE algorithm %s\n", *args);
					badarg = 1;
				}
			} else badarg = 1;
		} else if (!strcmp (*args, "-keypbe")) {
			if (args[1]) {
				args++;
				key_pbe=OBJ_txt2nid(*args);
				if(key_pbe == NID_undef) {
					BIO_printf(bio_err,
						 "Unknown PBE algorithm %s\n", *args);
					badarg = 1;
				}
			} else badarg = 1;
		} else if (!strcmp (*args, "-rand")) {
		    if (args[1]) {
			args++;	
			inrand = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-inkey")) {
		    if (args[1]) {
			args++;	
			keyname = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-certfile")) {
		    if (args[1]) {
			args++;	
			certfile = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-name")) {
		    if (args[1]) {
			args++;	
			name = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-CSP")) {
		    if (args[1]) {
			args++;	
			csp_name = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-caname")) {
		    if (args[1]) {
			args++;	
			if (!canames) canames = sk_new_null();
			sk_push(canames, *args);
		    } else badarg = 1;
		} else if (!strcmp (*args, "-in")) {
		    if (args[1]) {
			args++;	
			infile = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-out")) {
		    if (args[1]) {
			args++;	
			outfile = *args;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-passin")) {
		    if (args[1]) {
			args++;	
			passargin = *args;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-passout")) {
		    if (args[1]) {
			args++;	
			passargout = *args;
		    } else badarg = 1;
		} else if (!strcmp (*args, "-password")) {
		    if (args[1]) {
			args++;	
			passarg = *args;
		    	noprompt = 1;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-CApath")) {
		    if (args[1]) {
			args++;	
			CApath = *args;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-CAfile")) {
		    if (args[1]) {
			args++;	
			CAfile = *args;
		    } else badarg = 1;
		} else if (!strcmp(*args,"-engine")) {
		    if (args[1]) {
			args++;	
			engine = *args;
		    } else badarg = 1;
		} else badarg = 1;

	} else badarg = 1;
	args++;
    }

    if (badarg) {
	BIO_printf (bio_err, "Usage: pkcs12 [options]\n");
	BIO_printf (bio_err, "where options are\n");
	BIO_printf (bio_err, "-export       output PKCS12 file\n");
	BIO_printf (bio_err, "-chain        add certificate chain\n");
	BIO_printf (bio_err, "-inkey file   private key if not infile\n");
	BIO_printf (bio_err, "-certfile f   add all certs in f\n");
	BIO_printf (bio_err, "-CApath arg   - PEM format directory of CA's\n");
	BIO_printf (bio_err, "-CAfile arg   - PEM format file of CA's\n");
	BIO_printf (bio_err, "-name \"name\"  use name as friendly name\n");
	BIO_printf (bio_err, "-caname \"nm\"  use nm as CA friendly name (can be used more than once).\n");
	BIO_printf (bio_err, "-in  infile   input filename\n");
	BIO_printf (bio_err, "-out outfile  output filename\n");
	BIO_printf (bio_err, "-noout        don't output anything, just verify.\n");
	BIO_printf (bio_err, "-nomacver     don't verify MAC.\n");
	BIO_printf (bio_err, "-nocerts      don't output certificates.\n");
	BIO_printf (bio_err, "-clcerts      only output client certificates.\n");
	BIO_printf (bio_err, "-cacerts      only output CA certificates.\n");
	BIO_printf (bio_err, "-nokeys       don't output private keys.\n");
	BIO_printf (bio_err, "-info         give info about PKCS#12 structure.\n");
	BIO_printf (bio_err, "-des          encrypt private keys with DES\n");
	BIO_printf (bio_err, "-des3         encrypt private keys with triple DES (default)\n");
#ifndef OPENSSL_NO_IDEA
	BIO_printf (bio_err, "-idea         encrypt private keys with idea\n");
#endif
#ifndef OPENSSL_NO_AES
	BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
	BIO_printf (bio_err, "              encrypt PEM output with cbc aes\n");
#endif
	BIO_printf (bio_err, "-nodes        don't encrypt private keys\n");
	BIO_printf (bio_err, "-noiter       don't use encryption iteration\n");
	BIO_printf (bio_err, "-maciter      use MAC iteration\n");
	BIO_printf (bio_err, "-twopass      separate MAC, encryption passwords\n");
	BIO_printf (bio_err, "-descert      encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
	BIO_printf (bio_err, "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
	BIO_printf (bio_err, "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
	BIO_printf (bio_err, "-keyex        set MS key exchange type\n");
	BIO_printf (bio_err, "-keysig       set MS key signature type\n");
	BIO_printf (bio_err, "-password p   set import/export password source\n");
	BIO_printf (bio_err, "-passin p     input file pass phrase source\n");
	BIO_printf (bio_err, "-passout p    output file pass phrase source\n");
	BIO_printf (bio_err, "-engine e     use engine e, possibly a hardware device.\n");
	BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
	BIO_printf(bio_err,  "              load the file (or the files in the directory) into\n");
	BIO_printf(bio_err,  "              the random number generator\n");
    	goto end;
    }

    e = setup_engine(bio_err, engine, 0);

    if(passarg) {
	if(export_cert) passargout = passarg;
	else passargin = passarg;
    }

    if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
	BIO_printf(bio_err, "Error getting passwords\n");
	goto end;
    }

    if(!cpass) {
    	if(export_cert) cpass = passout;
    	else cpass = passin;
    }

    if(cpass) {
	mpass = cpass;
	noprompt = 1;
    } else {
	cpass = pass;
	mpass = macpass;
    }

    if(export_cert || inrand) {
    	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
        if (inrand != NULL)
		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
			app_RAND_load_files(inrand));
    }
    ERR_load_crypto_strings();

#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("read files");
#endif

    if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE);
    else in = BIO_new_file(infile, "rb");
    if (!in) {
	    BIO_printf(bio_err, "Error opening input file %s\n",
						infile ? infile : "<stdin>");
	    perror (infile);
	    goto end;
   }

#if 0
   if (certfile) {
    	if(!(certsin = BIO_new_file(certfile, "r"))) {
	    BIO_printf(bio_err, "Can't open certificate file %s\n", certfile);
	    perror (certfile);
	    goto end;
	}
    }

    if (keyname) {
    	if(!(inkey = BIO_new_file(keyname, "r"))) {
	    BIO_printf(bio_err, "Can't key certificate file %s\n", keyname);
	    perror (keyname);
	    goto end;
	}
     }
#endif

#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
    CRYPTO_push_info("write files");
#endif

    if (!outfile) {
	out = BIO_new_fp(stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	{
	    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	    out = BIO_push(tmpbio, out);
	}
#endif
    } else out = BIO_new_file(outfile, "wb");
    if (!out) {
	BIO_printf(bio_err, "Error opening output file %s\n",
						outfile ? outfile : "<stdout>");
	perror (outfile);
	goto end;
    }
    if (twopass) {
#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("read MAC password");
#endif
	if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:"******"Can't read Password\n");
    	    goto end;
       	}
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif
    }

    if (export_cert) {
	EVP_PKEY *key = NULL;
	STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
	STACK_OF(PKCS7) *safes = NULL;
	PKCS12_SAFEBAG *bag = NULL;
	PKCS8_PRIV_KEY_INFO *p8 = NULL;
	PKCS7 *authsafe = NULL;
	X509 *ucert = NULL;
	STACK_OF(X509) *certs=NULL;
	char *catmp = NULL;
	int i;
	unsigned char keyid[EVP_MAX_MD_SIZE];
	unsigned int keyidlen = 0;

#ifdef CRYPTO_MDEBUG
	CRYPTO_push_info("process -export_cert");
	CRYPTO_push_info("reading private key");
#endif
	key = load_key(bio_err, keyname ? keyname : infile, FORMAT_PEM, 1,
		passin, e, "private key");
	if (!key) {
		goto export_end;
	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from input");
#endif

	/* Load in all certs in input file */
	if(!(certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
		"certificates"))) {
		goto export_end;
	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from input 2");
#endif

	for(i = 0; i < sk_X509_num(certs); i++) {
		ucert = sk_X509_value(certs, i);
		if(X509_check_private_key(ucert, key)) {
			X509_digest(ucert, EVP_sha1(), keyid, &keyidlen);
			break;
		}
	}
	if(!keyidlen) {
		ucert = NULL;
		BIO_printf(bio_err, "No certificate matches private key\n");
		goto export_end;
	}
	
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("reading certs from certfile");
#endif

	bags = sk_PKCS12_SAFEBAG_new_null ();

	/* Add any more certificates asked for */
	if (certfile) {
		STACK_OF(X509) *morecerts=NULL;
		if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
					    NULL, e,
					    "certificates from certfile"))) {
			goto export_end;
		}
		while(sk_X509_num(morecerts) > 0) {
			sk_X509_push(certs, sk_X509_shift(morecerts));
		}
		sk_X509_free(morecerts);
 	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building chain");
#endif

	/* If chaining get chain from user cert */
	if (chain) {
        	int vret;
		STACK_OF(X509) *chain2;
		X509_STORE *store = X509_STORE_new();
		if (!store)
			{
			BIO_printf (bio_err, "Memory allocation error\n");
			goto export_end;
			}
		if (!X509_STORE_load_locations(store, CAfile, CApath))
			X509_STORE_set_default_paths (store);

		vret = get_cert_chain (ucert, store, &chain2);
		X509_STORE_free(store);

		if (!vret) {
		    /* Exclude verified certificate */
		    for (i = 1; i < sk_X509_num (chain2) ; i++) 
			sk_X509_push(certs, sk_X509_value (chain2, i));
		    /* Free first certificate */
		    X509_free(sk_X509_value(chain2, 0));
		    sk_X509_free(chain2);
		} else {
			BIO_printf (bio_err, "Error %s getting chain.\n",
					X509_verify_cert_error_string(vret));
			goto export_end;
		}			
    	}

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building bags");
#endif

	/* We now have loads of certificates: include them all */
	for(i = 0; i < sk_X509_num(certs); i++) {
		X509 *cert = NULL;
		cert = sk_X509_value(certs, i);
		bag = PKCS12_x5092certbag(cert);
		/* If it matches private key set id */
		if(cert == ucert) {
			if(name) PKCS12_add_friendlyname(bag, name, -1);
			PKCS12_add_localkeyid(bag, keyid, keyidlen);
		} else if((catmp = sk_shift(canames))) 
				PKCS12_add_friendlyname(bag, catmp, -1);
		sk_PKCS12_SAFEBAG_push(bags, bag);
	}
	sk_X509_pop_free(certs, X509_free);
	certs = NULL;

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("encrypting bags");
#endif

	if(!noprompt &&
		EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:"******"Can't read Password\n");
	    goto export_end;
        }
	if (!twopass) strcpy(macpass, pass);
	/* Turn certbags into encrypted authsafe */
	authsafe = PKCS12_pack_p7encdata(cert_pbe, cpass, -1, NULL, 0,
								 iter, bags);
	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;

	if (!authsafe) {
		ERR_print_errors (bio_err);
		goto export_end;
	}

	safes = sk_PKCS7_new_null ();
	sk_PKCS7_push (safes, authsafe);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building shrouded key bag");
#endif

	/* Make a shrouded key bag */
	p8 = EVP_PKEY2PKCS8 (key);
	if(keytype) PKCS8_add_keyusage(p8, keytype);
	bag = PKCS12_MAKE_SHKEYBAG(key_pbe, cpass, -1, NULL, 0, iter, p8);
	PKCS8_PRIV_KEY_INFO_free(p8);
	p8 = NULL;
        if (name) PKCS12_add_friendlyname (bag, name, -1);
	if(csp_name) PKCS12_add_CSPName_asc(bag, csp_name, -1);
	PKCS12_add_localkeyid (bag, keyid, keyidlen);
	bags = sk_PKCS12_SAFEBAG_new_null();
	sk_PKCS12_SAFEBAG_push (bags, bag);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("encrypting shrouded key bag");
#endif

	/* Turn it into unencrypted safe bag */
	authsafe = PKCS12_pack_p7data (bags);
	sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
	bags = NULL;
	sk_PKCS7_push (safes, authsafe);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("building pkcs12");
#endif

	p12 = PKCS12_init(NID_pkcs7_data);

	PKCS12_pack_authsafes(p12, safes);

	sk_PKCS7_pop_free(safes, PKCS7_free);
	safes = NULL;

	PKCS12_set_mac (p12, mpass, -1, NULL, 0, maciter, NULL);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("writing pkcs12");
#endif

	i2d_PKCS12_bio (out, p12);

	ret = 0;

    export_end:
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_pop_info();
	CRYPTO_push_info("process -export_cert: freeing");
#endif

	if (key) EVP_PKEY_free(key);
	if (certs) sk_X509_pop_free(certs, X509_free);
	if (safes) sk_PKCS7_pop_free(safes, PKCS7_free);
	if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);

#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
#endif
	goto end;
	
    }

    if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
	ERR_print_errors(bio_err);
	goto end;
    }

#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("read import password");
#endif
    if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:"******"Can't read Password\n");
	goto end;
    }
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif

    if (!twopass) strcpy(macpass, pass);

    if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
    if(macver) {
#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("verify MAC");
#endif
	/* If we enter empty password try no password first */
	if(!macpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
		/* If mac and crypto pass the same set it to NULL too */
		if(!twopass) cpass = NULL;
	} else if (!PKCS12_verify_mac(p12, mpass, -1)) {
	    BIO_printf (bio_err, "Mac verify error: invalid password?\n");
	    ERR_print_errors (bio_err);
	    goto end;
	}
	BIO_printf (bio_err, "MAC verified OK\n");
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif
    }

#ifdef CRYPTO_MDEBUG
    CRYPTO_push_info("output keys and certificates");
#endif
    if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) {
	BIO_printf(bio_err, "Error outputting keys and certificates\n");
	ERR_print_errors (bio_err);
	goto end;
    }
#ifdef CRYPTO_MDEBUG
    CRYPTO_pop_info();
#endif
    ret = 0;
 end:
    if (p12) PKCS12_free(p12);
    if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
#ifdef CRYPTO_MDEBUG
    CRYPTO_remove_all_info();
#endif
    BIO_free(in);
    BIO_free_all(out);
    if (canames) sk_free(canames);
    if(passin) OPENSSL_free(passin);
    if(passout) OPENSSL_free(passout);
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Пример #22
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;
}
Пример #23
0
int
pkcs12_main(int argc, char **argv)
{
	ENGINE *e = NULL;
	char *infile = NULL, *outfile = NULL, *keyname = NULL;
	char *certfile = NULL;
	BIO *in = NULL, *out = NULL;
	char **args;
	char *name = NULL;
	char *csp_name = NULL;
	int add_lmk = 0;
	PKCS12 *p12 = NULL;
	char pass[50], macpass[50];
	int export_cert = 0;
	int options = 0;
	int chain = 0;
	int badarg = 0;
	int iter = PKCS12_DEFAULT_ITER;
	int maciter = PKCS12_DEFAULT_ITER;
	int twopass = 0;
	int keytype = 0;
	int cert_pbe;
	int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
	int ret = 1;
	int macver = 1;
	int noprompt = 0;
	STACK_OF(OPENSSL_STRING) * canames = NULL;
	char *cpass = NULL, *mpass = NULL;
	char *passargin = NULL, *passargout = NULL, *passarg = NULL;
	char *passin = NULL, *passout = NULL;
	char *inrand = NULL;
	char *macalg = NULL;
	char *CApath = NULL, *CAfile = NULL;
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif

	signal(SIGPIPE, SIG_IGN);

	cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;

	enc = EVP_des_ede3_cbc();
	if (bio_err == NULL)
		bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;

	args = argv + 1;


	while (*args) {
		if (*args[0] == '-') {
			if (!strcmp(*args, "-nokeys"))
				options |= NOKEYS;
			else if (!strcmp(*args, "-keyex"))
				keytype = KEY_EX;
			else if (!strcmp(*args, "-keysig"))
				keytype = KEY_SIG;
			else if (!strcmp(*args, "-nocerts"))
				options |= NOCERTS;
			else if (!strcmp(*args, "-clcerts"))
				options |= CLCERTS;
			else if (!strcmp(*args, "-cacerts"))
				options |= CACERTS;
			else if (!strcmp(*args, "-noout"))
				options |= (NOKEYS | NOCERTS);
			else if (!strcmp(*args, "-info"))
				options |= INFO;
			else if (!strcmp(*args, "-chain"))
				chain = 1;
			else if (!strcmp(*args, "-twopass"))
				twopass = 1;
			else if (!strcmp(*args, "-nomacver"))
				macver = 0;
			else if (!strcmp(*args, "-descert"))
				cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
			else if (!strcmp(*args, "-export"))
				export_cert = 1;
			else if (!strcmp(*args, "-des"))
				enc = EVP_des_cbc();
			else if (!strcmp(*args, "-des3"))
				enc = EVP_des_ede3_cbc();
#ifndef OPENSSL_NO_IDEA
			else if (!strcmp(*args, "-idea"))
				enc = EVP_idea_cbc();
#endif
#ifndef OPENSSL_NO_SEED
			else if (!strcmp(*args, "-seed"))
				enc = EVP_seed_cbc();
#endif
#ifndef OPENSSL_NO_AES
			else if (!strcmp(*args, "-aes128"))
				enc = EVP_aes_128_cbc();
			else if (!strcmp(*args, "-aes192"))
				enc = EVP_aes_192_cbc();
			else if (!strcmp(*args, "-aes256"))
				enc = EVP_aes_256_cbc();
#endif
#ifndef OPENSSL_NO_CAMELLIA
			else if (!strcmp(*args, "-camellia128"))
				enc = EVP_camellia_128_cbc();
			else if (!strcmp(*args, "-camellia192"))
				enc = EVP_camellia_192_cbc();
			else if (!strcmp(*args, "-camellia256"))
				enc = EVP_camellia_256_cbc();
#endif
			else if (!strcmp(*args, "-noiter"))
				iter = 1;
			else if (!strcmp(*args, "-maciter"))
				maciter = PKCS12_DEFAULT_ITER;
			else if (!strcmp(*args, "-nomaciter"))
				maciter = 1;
			else if (!strcmp(*args, "-nomac"))
				maciter = -1;
			else if (!strcmp(*args, "-macalg"))
				if (args[1]) {
					args++;
					macalg = *args;
				} else
					badarg = 1;
			else if (!strcmp(*args, "-nodes"))
				enc = NULL;
			else if (!strcmp(*args, "-certpbe")) {
				if (!set_pbe(bio_err, &cert_pbe, *++args))
					badarg = 1;
			} else if (!strcmp(*args, "-keypbe")) {
				if (!set_pbe(bio_err, &key_pbe, *++args))
					badarg = 1;
			} else if (!strcmp(*args, "-rand")) {
				if (args[1]) {
					args++;
					inrand = *args;
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-inkey")) {
				if (args[1]) {
					args++;
					keyname = *args;
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-certfile")) {
				if (args[1]) {
					args++;
					certfile = *args;
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-name")) {
				if (args[1]) {
					args++;
					name = *args;
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-LMK"))
				add_lmk = 1;
			else if (!strcmp(*args, "-CSP")) {
				if (args[1]) {
					args++;
					csp_name = *args;
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-caname")) {
				if (args[1]) {
					args++;
					if (!canames)
						canames = sk_OPENSSL_STRING_new_null();
					sk_OPENSSL_STRING_push(canames, *args);
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-in")) {
				if (args[1]) {
					args++;
					infile = *args;
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-out")) {
				if (args[1]) {
					args++;
					outfile = *args;
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-passin")) {
				if (args[1]) {
					args++;
					passargin = *args;
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-passout")) {
				if (args[1]) {
					args++;
					passargout = *args;
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-password")) {
				if (args[1]) {
					args++;
					passarg = *args;
					noprompt = 1;
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-CApath")) {
				if (args[1]) {
					args++;
					CApath = *args;
				} else
					badarg = 1;
			} else if (!strcmp(*args, "-CAfile")) {
				if (args[1]) {
					args++;
					CAfile = *args;
				} else
					badarg = 1;
#ifndef OPENSSL_NO_ENGINE
			} else if (!strcmp(*args, "-engine")) {
				if (args[1]) {
					args++;
					engine = *args;
				} else
					badarg = 1;
#endif
			} else
				badarg = 1;

		} else
			badarg = 1;
		args++;
	}

	if (badarg) {
		BIO_printf(bio_err, "Usage: pkcs12 [options]\n");
		BIO_printf(bio_err, "where options are\n");
		BIO_printf(bio_err, "-export       output PKCS12 file\n");
		BIO_printf(bio_err, "-chain        add certificate chain\n");
		BIO_printf(bio_err, "-inkey file   private key if not infile\n");
		BIO_printf(bio_err, "-certfile f   add all certs in f\n");
		BIO_printf(bio_err, "-CApath arg   - PEM format directory of CA's\n");
		BIO_printf(bio_err, "-CAfile arg   - PEM format file of CA's\n");
		BIO_printf(bio_err, "-name \"name\"  use name as friendly name\n");
		BIO_printf(bio_err, "-caname \"nm\"  use nm as CA friendly name (can be used more than once).\n");
		BIO_printf(bio_err, "-in  infile   input filename\n");
		BIO_printf(bio_err, "-out outfile  output filename\n");
		BIO_printf(bio_err, "-noout        don't output anything, just verify.\n");
		BIO_printf(bio_err, "-nomacver     don't verify MAC.\n");
		BIO_printf(bio_err, "-nocerts      don't output certificates.\n");
		BIO_printf(bio_err, "-clcerts      only output client certificates.\n");
		BIO_printf(bio_err, "-cacerts      only output CA certificates.\n");
		BIO_printf(bio_err, "-nokeys       don't output private keys.\n");
		BIO_printf(bio_err, "-info         give info about PKCS#12 structure.\n");
		BIO_printf(bio_err, "-des          encrypt private keys with DES\n");
		BIO_printf(bio_err, "-des3         encrypt private keys with triple DES (default)\n");
#ifndef OPENSSL_NO_IDEA
		BIO_printf(bio_err, "-idea         encrypt private keys with idea\n");
#endif
#ifndef OPENSSL_NO_SEED
		BIO_printf(bio_err, "-seed         encrypt private keys with seed\n");
#endif
#ifndef OPENSSL_NO_AES
		BIO_printf(bio_err, "-aes128, -aes192, -aes256\n");
		BIO_printf(bio_err, "              encrypt PEM output with cbc aes\n");
#endif
#ifndef OPENSSL_NO_CAMELLIA
		BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n");
		BIO_printf(bio_err, "              encrypt PEM output with cbc camellia\n");
#endif
		BIO_printf(bio_err, "-nodes        don't encrypt private keys\n");
		BIO_printf(bio_err, "-noiter       don't use encryption iteration\n");
		BIO_printf(bio_err, "-nomaciter    don't use MAC iteration\n");
		BIO_printf(bio_err, "-maciter      use MAC iteration\n");
		BIO_printf(bio_err, "-nomac        don't generate MAC\n");
		BIO_printf(bio_err, "-twopass      separate MAC, encryption passwords\n");
		BIO_printf(bio_err, "-descert      encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
		BIO_printf(bio_err, "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
		BIO_printf(bio_err, "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
		BIO_printf(bio_err, "-macalg alg   digest algorithm used in MAC (default SHA1)\n");
		BIO_printf(bio_err, "-keyex        set MS key exchange type\n");
		BIO_printf(bio_err, "-keysig       set MS key signature type\n");
		BIO_printf(bio_err, "-password p   set import/export password source\n");
		BIO_printf(bio_err, "-passin p     input file pass phrase source\n");
		BIO_printf(bio_err, "-passout p    output file pass phrase source\n");
#ifndef OPENSSL_NO_ENGINE
		BIO_printf(bio_err, "-engine e     use engine e, possibly a hardware device.\n");
#endif
		BIO_printf(bio_err, "-rand file:file:...\n");
		BIO_printf(bio_err, "              load the file (or the files in the directory) into\n");
		BIO_printf(bio_err, "              the random number generator\n");
		BIO_printf(bio_err, "-CSP name     Microsoft CSP name\n");
		BIO_printf(bio_err, "-LMK          Add local machine keyset attribute to private key\n");
		goto end;
	}
#ifndef OPENSSL_NO_ENGINE
	e = setup_engine(bio_err, engine, 0);
#endif

	if (passarg) {
		if (export_cert)
			passargout = passarg;
		else
			passargin = passarg;
	}
	if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
		BIO_printf(bio_err, "Error getting passwords\n");
		goto end;
	}
	if (!cpass) {
		if (export_cert)
			cpass = passout;
		else
			cpass = passin;
	}
	if (cpass) {
		mpass = cpass;
		noprompt = 1;
	} else {
		cpass = pass;
		mpass = macpass;
	}

	ERR_load_crypto_strings();

#ifdef CRYPTO_MDEBUG
	CRYPTO_push_info("read files");
#endif

	if (!infile)
		in = BIO_new_fp(stdin, BIO_NOCLOSE);
	else
		in = BIO_new_file(infile, "rb");
	if (!in) {
		BIO_printf(bio_err, "Error opening input file %s\n",
		    infile ? infile : "<stdin>");
		perror(infile);
		goto end;
	}
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
	CRYPTO_push_info("write files");
#endif

	if (!outfile) {
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
	} else
		out = BIO_new_file(outfile, "wb");
	if (!out) {
		BIO_printf(bio_err, "Error opening output file %s\n",
		    outfile ? outfile : "<stdout>");
		perror(outfile);
		goto end;
	}
	if (twopass) {
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("read MAC password");
#endif
		if (EVP_read_pw_string(macpass, sizeof macpass, "Enter MAC Password:"******"Can't read Password\n");
			goto end;
		}
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif
	}
	if (export_cert) {
		EVP_PKEY *key = NULL;
		X509 *ucert = NULL, *x = NULL;
		STACK_OF(X509) * certs = NULL;
		const EVP_MD *macmd = NULL;
		unsigned char *catmp = NULL;
		int i;

		if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
			BIO_printf(bio_err, "Nothing to do!\n");
			goto export_end;
		}
		if (options & NOCERTS)
			chain = 0;

#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("process -export_cert");
		CRYPTO_push_info("reading private key");
#endif
		if (!(options & NOKEYS)) {
			key = load_key(bio_err, keyname ? keyname : infile,
			    FORMAT_PEM, 1, passin, e, "private key");
			if (!key)
				goto export_end;
		}
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
		CRYPTO_push_info("reading certs from input");
#endif

		/* Load in all certs in input file */
		if (!(options & NOCERTS)) {
			certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
			    "certificates");
			if (!certs)
				goto export_end;

			if (key) {
				/* Look for matching private key */
				for (i = 0; i < sk_X509_num(certs); i++) {
					x = sk_X509_value(certs, i);
					if (X509_check_private_key(x, key)) {
						ucert = x;
						/* Zero keyid and alias */
						X509_keyid_set1(ucert, NULL, 0);
						X509_alias_set1(ucert, NULL, 0);
						/* Remove from list */
						(void) sk_X509_delete(certs, i);
						break;
					}
				}
				if (!ucert) {
					BIO_printf(bio_err, "No certificate matches private key\n");
					goto export_end;
				}
			}
		}
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
		CRYPTO_push_info("reading certs from input 2");
#endif

		/* Add any more certificates asked for */
		if (certfile) {
			STACK_OF(X509) * morecerts = NULL;
			if (!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
				    NULL, e,
				    "certificates from certfile")))
				goto export_end;
			while (sk_X509_num(morecerts) > 0)
				sk_X509_push(certs, sk_X509_shift(morecerts));
			sk_X509_free(morecerts);
		}
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
		CRYPTO_push_info("reading certs from certfile");
#endif

#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
		CRYPTO_push_info("building chain");
#endif

		/* If chaining get chain from user cert */
		if (chain) {
			int vret;
			STACK_OF(X509) * chain2;
			X509_STORE *store = X509_STORE_new();
			if (!store) {
				BIO_printf(bio_err, "Memory allocation error\n");
				goto export_end;
			}
			if (!X509_STORE_load_locations(store, CAfile, CApath))
				X509_STORE_set_default_paths(store);

			vret = get_cert_chain(ucert, store, &chain2);
			X509_STORE_free(store);

			if (!vret) {
				/* Exclude verified certificate */
				for (i = 1; i < sk_X509_num(chain2); i++)
					sk_X509_push(certs, sk_X509_value(chain2, i));
				/* Free first certificate */
				X509_free(sk_X509_value(chain2, 0));
				sk_X509_free(chain2);
			} else {
				if (vret >= 0)
					BIO_printf(bio_err, "Error %s getting chain.\n",
					    X509_verify_cert_error_string(vret));
				else
					ERR_print_errors(bio_err);
				goto export_end;
			}
		}
		/* Add any CA names */

		for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) {
			catmp = (unsigned char *) sk_OPENSSL_STRING_value(canames, i);
			X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
		}

		if (csp_name && key)
			EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
			    MBSTRING_ASC, (unsigned char *) csp_name, -1);

		if (add_lmk && key)
			EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);

#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
		CRYPTO_push_info("reading password");
#endif

		if (!noprompt &&
		    EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:"******"Can't read Password\n");
			goto export_end;
		}
		if (!twopass)
			strlcpy(macpass, pass, sizeof macpass);

#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
		CRYPTO_push_info("creating PKCS#12 structure");
#endif

		p12 = PKCS12_create(cpass, name, key, ucert, certs,
		    key_pbe, cert_pbe, iter, -1, keytype);

		if (!p12) {
			ERR_print_errors(bio_err);
			goto export_end;
		}
		if (macalg) {
			macmd = EVP_get_digestbyname(macalg);
			if (!macmd) {
				BIO_printf(bio_err, "Unknown digest algorithm %s\n",
				    macalg);
			}
		}
		if (maciter != -1)
			PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);

#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
		CRYPTO_push_info("writing pkcs12");
#endif

		i2d_PKCS12_bio(out, p12);

		ret = 0;

export_end:
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
		CRYPTO_pop_info();
		CRYPTO_push_info("process -export_cert: freeing");
#endif

		if (key)
			EVP_PKEY_free(key);
		if (certs)
			sk_X509_pop_free(certs, X509_free);
		if (ucert)
			X509_free(ucert);

#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif
		goto end;

	}
	if (!(p12 = d2i_PKCS12_bio(in, NULL))) {
		ERR_print_errors(bio_err);
		goto end;
	}
#ifdef CRYPTO_MDEBUG
	CRYPTO_push_info("read import password");
#endif
	if (!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:"******"Can't read Password\n");
		goto end;
	}
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
#endif

	if (!twopass)
		strlcpy(macpass, pass, sizeof macpass);

	if ((options & INFO) && p12->mac)
		BIO_printf(bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1);
	if (macver) {
#ifdef CRYPTO_MDEBUG
		CRYPTO_push_info("verify MAC");
#endif
		/* If we enter empty password try no password first */
		if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
			/* If mac and crypto pass the same set it to NULL too */
			if (!twopass)
				cpass = NULL;
		} else if (!PKCS12_verify_mac(p12, mpass, -1)) {
			BIO_printf(bio_err, "Mac verify error: invalid password?\n");
			ERR_print_errors(bio_err);
			goto end;
		}
		BIO_printf(bio_err, "MAC verified OK\n");
#ifdef CRYPTO_MDEBUG
		CRYPTO_pop_info();
#endif
	}
#ifdef CRYPTO_MDEBUG
	CRYPTO_push_info("output keys and certificates");
#endif
	if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout)) {
		BIO_printf(bio_err, "Error outputting keys and certificates\n");
		ERR_print_errors(bio_err);
		goto end;
	}
#ifdef CRYPTO_MDEBUG
	CRYPTO_pop_info();
#endif
	ret = 0;
end:
	if (p12)
		PKCS12_free(p12);
#ifdef CRYPTO_MDEBUG
	CRYPTO_remove_all_info();
#endif
	BIO_free(in);
	BIO_free_all(out);
	if (canames)
		sk_OPENSSL_STRING_free(canames);
	if (passin)
		free(passin);
	if (passout)
		free(passout);
	
	return (ret);
}
Пример #24
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;
}
Пример #25
0
static Bool
LoadPKCS12(SSL_CTX *ctx, const char *file)
{
	char passbuf[256];
	char *pass = NULL;
	PKCS12 *p12;
	EVP_PKEY *key = NULL;
	X509 *cert = NULL;
	BIO *input;
	int err_reason;
	int count = 0;
	const char *prompt = ASKPASS_PROMPT;
	
	/* read PKCS #12 from specified file */
	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;

	/* get key and cert from  PKCS #12 */
	for (;;){
	if (PKCS12_parse(p12, pass, &key, &cert, NULL))
		break;
	err_reason = ERR_GET_REASON(ERR_peek_error());
	if (cert){ X509_free(cert); cert = NULL; }
	if (key){ EVP_PKEY_free(key); key = NULL; }
	if (err_reason != PKCS12_R_MAC_VERIFY_FAILURE){
		Message("PKCS12_parse failure: %s", GetSSLErrorString());
		break;
	}
	ERR_clear_error();
	if (count >= 1) prompt = ASKPASS_PROMPT_RETRY;
	if ((pass = GetPasswordString(passbuf, sizeof(passbuf), prompt)) == NULL){
		Message("PASSWORD input was canceled\n");
		break;
	}
	count++;
	}
	//OPENSSL_cleanse(passbuf, sizeof(passbuf));
	memset(passbuf, 0, sizeof(passbuf));
	PKCS12_free(p12);
	
	/* set key and cert to SSL_CTX */
	if (cert && key){
		if (!SSL_CTX_use_certificate_with_check(ctx, cert)){
			SSL_Error(_d("SSL_CTX_use_certificate failure:\n %s"), GetSSLErrorString());
			return FALSE;
		}
		if (!SSL_CTX_use_PrivateKey(ctx, key)){
			SSL_Error(_d("SSL_CTX_use_PrivateKey failure:\n %s"), GetSSLErrorString());
			return FALSE;
		}
		if (!SSL_CTX_check_private_key(ctx)){
			SSL_Error(_d("SSL_CTX_check_private_key failure:\n %s\n"),
				GetSSLErrorString());
			return FALSE;
		}
	}
	else{
		return FALSE;
	}

	return TRUE;
}
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;
    
}
Пример #27
0
int pkcs12_main(int argc, char **argv)
{
    char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL;
    char *name = NULL, *csp_name = NULL;
    char pass[50], macpass[50];
    int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0;
    int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER;
# ifndef OPENSSL_NO_RC2
    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
# else
    int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
# endif
    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
    int ret = 1, macver = 1, noprompt = 0, add_lmk = 0;
    char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL;
    char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL;
    char *cpass = NULL, *mpass = NULL, *CApath = NULL, *CAfile = NULL;
    char *prog;
    ENGINE *e = NULL;
    BIO *in = NULL, *out = NULL;
    PKCS12 *p12 = NULL;
    STACK_OF(OPENSSL_STRING) *canames = NULL;
    const EVP_CIPHER *enc = EVP_des_ede3_cbc();
    OPTION_CHOICE o;

    prog = opt_init(argc, argv, pkcs12_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(pkcs12_options);
            ret = 0;
            goto end;
        case OPT_NOKEYS:
            options |= NOKEYS;
            break;
        case OPT_KEYEX:
            keytype = KEY_EX;
            break;
        case OPT_KEYSIG:
            keytype = KEY_SIG;
            break;
        case OPT_NOCERTS:
            options |= NOCERTS;
            break;
        case OPT_CLCERTS:
            options |= CLCERTS;
            break;
        case OPT_CACERTS:
            options |= CACERTS;
            break;
        case OPT_NOOUT:
            options |= (NOKEYS | NOCERTS);
            break;
        case OPT_INFO:
            options |= INFO;
            break;
        case OPT_CHAIN:
            chain = 1;
            break;
        case OPT_TWOPASS:
            twopass = 1;
            break;
        case OPT_NOMACVER:
            macver = 0;
            break;
        case OPT_DESCERT:
            cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
            break;
        case OPT_EXPORT:
            export_cert = 1;
            break;
        case OPT_CIPHER:
            if (!opt_cipher(opt_unknown(), &enc))
                goto opthelp;
            break;
        case OPT_NOITER:
            iter = 1;
            break;
        case OPT_MACITER:
            maciter = PKCS12_DEFAULT_ITER;
            break;
        case OPT_NOMACITER:
            maciter = 1;
            break;
        case OPT_NOMAC:
            maciter = -1;
            break;
        case OPT_MACALG:
            macalg = opt_arg();
            break;
        case OPT_NODES:
            enc = NULL;
            break;
        case OPT_CERTPBE:
            if (!set_pbe(&cert_pbe, opt_arg()))
                goto opthelp;
            break;
        case OPT_KEYPBE:
            if (!set_pbe(&key_pbe, opt_arg()))
                goto opthelp;
            break;
        case OPT_RAND:
            inrand = opt_arg();
            break;
        case OPT_INKEY:
            keyname = opt_arg();
            break;
        case OPT_CERTFILE:
            certfile = opt_arg();
            break;
        case OPT_NAME:
            name = opt_arg();
            break;
        case OPT_LMK:
            add_lmk = 1;
            break;
        case OPT_CSP:
            csp_name = opt_arg();
            break;
        case OPT_CANAME:
            if (canames == NULL
                && (canames = sk_OPENSSL_STRING_new_null()) == NULL)
                goto end;
            sk_OPENSSL_STRING_push(canames, opt_arg());
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_PASSOUT:
            passoutarg = opt_arg();
            break;
        case OPT_PASSWORD:
            passarg = opt_arg();
            break;
        case OPT_CAPATH:
            CApath = opt_arg();
            break;
        case OPT_CAFILE:
            CAfile = opt_arg();
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (passarg) {
        if (export_cert)
            passoutarg = passarg;
        else
            passinarg = passarg;
    }

    if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
        BIO_printf(bio_err, "Error getting passwords\n");
        goto end;
    }

    if (!cpass) {
        if (export_cert)
            cpass = passout;
        else
            cpass = passin;
    }

    if (cpass) {
        mpass = cpass;
        noprompt = 1;
    } else {
        cpass = pass;
        mpass = macpass;
    }

    if (export_cert || inrand) {
        app_RAND_load_file(NULL, (inrand != NULL));
        if (inrand != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(inrand));
    }

    in = bio_open_default(infile, "rb");
    if (in == NULL)
        goto end;

    out = bio_open_default(outfile, "wb");
    if (out == NULL)
        goto end;

    if (twopass) {
        if (EVP_read_pw_string
            (macpass, sizeof macpass, "Enter MAC Password:"******"Can't read Password\n");
            goto end;
        }
    }

    if (export_cert) {
        EVP_PKEY *key = NULL;
        X509 *ucert = NULL, *x = NULL;
        STACK_OF(X509) *certs = NULL;
        const EVP_MD *macmd = NULL;
        unsigned char *catmp = NULL;
        int i;

        if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
            BIO_printf(bio_err, "Nothing to do!\n");
            goto export_end;
        }

        if (options & NOCERTS)
            chain = 0;

        if (!(options & NOKEYS)) {
            key = load_key(keyname ? keyname : infile,
                           FORMAT_PEM, 1, passin, e, "private key");
            if (!key)
                goto export_end;
        }

        /* Load in all certs in input file */
        if (!(options & NOCERTS)) {
            certs = load_certs(infile, FORMAT_PEM, NULL, e,
                               "certificates");
            if (!certs)
                goto export_end;

            if (key) {
                /* Look for matching private key */
                for (i = 0; i < sk_X509_num(certs); i++) {
                    x = sk_X509_value(certs, i);
                    if (X509_check_private_key(x, key)) {
                        ucert = x;
                        /* Zero keyid and alias */
                        X509_keyid_set1(ucert, NULL, 0);
                        X509_alias_set1(ucert, NULL, 0);
                        /* Remove from list */
                        (void)sk_X509_delete(certs, i);
                        break;
                    }
                }
                if (!ucert) {
                    BIO_printf(bio_err,
                               "No certificate matches private key\n");
                    goto export_end;
                }
            }

        }

        /* Add any more certificates asked for */
        if (certfile) {
            STACK_OF(X509) *morecerts = NULL;
            if (!(morecerts = load_certs(certfile, FORMAT_PEM, NULL, e,
                                         "certificates from certfile")))
                goto export_end;
            while (sk_X509_num(morecerts) > 0)
                sk_X509_push(certs, sk_X509_shift(morecerts));
            sk_X509_free(morecerts);
        }

        /* If chaining get chain from user cert */
        if (chain) {
            int vret;
            STACK_OF(X509) *chain2;
            X509_STORE *store;
            if (!(store = setup_verify(CAfile, CApath)))
                goto export_end;

            vret = get_cert_chain(ucert, store, &chain2);
            X509_STORE_free(store);

            if (!vret) {
                /* Exclude verified certificate */
                for (i = 1; i < sk_X509_num(chain2); i++)
                    sk_X509_push(certs, sk_X509_value(chain2, i));
                /* Free first certificate */
                X509_free(sk_X509_value(chain2, 0));
                sk_X509_free(chain2);
            } else {
                if (vret >= 0)
                    BIO_printf(bio_err, "Error %s getting chain.\n",
                               X509_verify_cert_error_string(vret));
                else
                    ERR_print_errors(bio_err);
                goto export_end;
            }
        }

        /* Add any CA names */

        for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) {
            catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
            X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
        }

        if (csp_name && key)
            EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
                                      MBSTRING_ASC, (unsigned char *)csp_name,
                                      -1);

        if (add_lmk && key)
            EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);

        if (!noprompt &&
            EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:"******"Can't read Password\n");
            goto export_end;
        }
        if (!twopass)
            BUF_strlcpy(macpass, pass, sizeof macpass);

        p12 = PKCS12_create(cpass, name, key, ucert, certs,
                            key_pbe, cert_pbe, iter, -1, keytype);

        if (!p12) {
            ERR_print_errors(bio_err);
            goto export_end;
        }

        if (macalg) {
            if (!opt_md(macalg, &macmd))
                goto opthelp;
        }

        if (maciter != -1)
            PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);

        i2d_PKCS12_bio(out, p12);

        ret = 0;

 export_end:

        EVP_PKEY_free(key);
        if (certs)
            sk_X509_pop_free(certs, X509_free);
        if (ucert)
            X509_free(ucert);

        goto end;

    }

    if (!(p12 = d2i_PKCS12_bio(in, NULL))) {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (!noprompt
        && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:"******"Can't read Password\n");
        goto end;
    }

    if (!twopass)
        BUF_strlcpy(macpass, pass, sizeof macpass);

    if ((options & INFO) && p12->mac)
        BIO_printf(bio_err, "MAC Iteration %ld\n",
                   p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1);
    if (macver) {
        /* If we enter empty password try no password first */
        if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
            /* If mac and crypto pass the same set it to NULL too */
            if (!twopass)
                cpass = NULL;
        } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
            BIO_printf(bio_err, "Mac verify error: invalid password?\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout, enc)) {
        BIO_printf(bio_err, "Error outputting keys and certificates\n");
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
 end:
    PKCS12_free(p12);
    if (export_cert || inrand)
        app_RAND_write_file(NULL);
    BIO_free(in);
    BIO_free_all(out);
    if (canames)
        sk_OPENSSL_STRING_free(canames);
    if (passin)
        OPENSSL_free(passin);
    if (passout)
        OPENSSL_free(passout);
    return (ret);
}
Пример #28
0
/*============================================================================
 * 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;
}
Пример #29
0
Файл: app.c Проект: symma/xmlsec
    PKCS12 *p12 = NULL;
    EVP_PKEY *pKey = NULL;
    STACK_OF(X509) *chain = NULL;
    xmlSecKeyPtr key = NULL;
    xmlSecKeyDataPtr data = NULL;
    xmlSecKeyDataPtr x509Data = NULL;
    X509 *cert = NULL;
    X509 *tmpcert = NULL;
    int i;
    int has_cert;
    int ret;

    xmlSecAssert2(bio != NULL, NULL);

    p12 = d2i_PKCS12_bio(bio, NULL);
    if(p12 == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "d2i_PKCS12_fp",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        goto done;
    }

    ret = PKCS12_verify_mac(p12, pwd, (pwd != NULL) ? strlen(pwd) : 0);
    if(ret != 1) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "PKCS12_verify_mac",
                    XMLSEC_ERRORS_R_CRYPTO_FAILED,