Ejemplo n.º 1
0
static int
_parcPkcs12KeyStore_ParseFile(PARCPkcs12KeyStore *keystore, const char *filename, const char *password)
{
    parcSecurity_AssertIsInitialized();

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

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

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

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

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

    keystore->public_key = X509_get_pubkey(keystore->x509_cert);
    return 0;
}
Ejemplo n.º 2
0
int
useCertFile(SSL_CTX* ctx, const char* path, const char* passphrase, const char* cacertfile)
{
    FILE *p12_file;
    PKCS12 *p12_cert = NULL;
    EVP_PKEY *pkey;
    X509 *x509_cert;
    
    p12_file = fopen(path, "r");
    if (!p12_file)
    {
        timestamp_f(stderr);
        perror(path);
        return -1;
    }

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

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

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

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

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

    return 0;
}
Ejemplo n.º 3
0
pki_pkcs12::pki_pkcs12(const QString fname, pem_password_cb *cb)
	:pki_base(fname)
{
	FILE *fp;
	char pass[MAX_PASS_LENGTH];
	EVP_PKEY *mykey = NULL;
	X509 *mycert = NULL;
	key=NULL; cert=NULL;
	passcb = cb;
	class_name="pki_pkcs12";
	certstack = sk_X509_new_null();
	pass_info p(XCA_TITLE, tr("Please enter the password to decrypt the PKCS#12 file.")
		+ "\n'" + fname + "'");
	fp = fopen(QString2filename(fname), "rb");
	if (fp) {
		PKCS12 *pkcs12 = d2i_PKCS12_fp(fp, NULL);
		fclose(fp);
		if (ign_openssl_error()) {
			if (pkcs12)
				PKCS12_free(pkcs12);
			throw errorEx(tr("Unable to load the PKCS#12 (pfx) file %1.").arg(fname));
		}
		if (PKCS12_verify_mac(pkcs12, "", 0) || PKCS12_verify_mac(pkcs12, NULL, 0))
			pass[0] = '\0';
		else if (passcb(pass, MAX_PASS_LENGTH, 0, &p) < 0) {
			/* cancel pressed */
			PKCS12_free(pkcs12);
			throw errorEx("","");
		}
		PKCS12_parse(pkcs12, pass, &mykey, &mycert, &certstack);
		int error = ERR_peek_error();
		if (ERR_GET_REASON(error) == PKCS12_R_MAC_VERIFY_FAILURE) {
			ign_openssl_error();
			PKCS12_free(pkcs12);
			throw errorEx(getClassName(), tr("The supplied password was wrong (%1)").arg(ERR_reason_error_string(error)));
		}
		ign_openssl_error();
		if (mycert) {
			if (mycert->aux && mycert->aux->alias) {
				alias = asn1ToQString(mycert->aux->alias);
				alias = QString::fromUtf8(alias.toAscii());
			}
			cert = new pki_x509(mycert);
			if (alias.isEmpty()) {
				cert->autoIntName();
			} else {
				cert->setIntName(alias);
			}
			alias = cert->getIntName();
		}
		if (mykey) {
			key = new pki_evp(mykey);
			key->setIntName(alias + "_key");
			key->bogusEncryptKey();
		}
		PKCS12_free(pkcs12);
	} else
		fopen_error(fname);
}
int sign_with_rsa_sha256(const char *input, const char *private_key, unsigned char *buffer_out, int *buffer_out_len) {

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

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

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

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

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

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

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

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

  return 0;
}
Ejemplo n.º 5
0
int main(int argc, char **argv)
{
	FILE *fp;
	EVP_PKEY *pkey;
	X509 *cert;
	STACK_OF(X509) *ca = NULL;
	PKCS12 *p12;
	int i;
	if (argc != 4) {
		fprintf(stderr, "Usage: pkread p12file password opfile\n");
		exit (1);
	}
	SSLeay_add_all_algorithms();
	ERR_load_crypto_strings();
	if (!(fp = fopen(argv[1], "rb"))) {
		fprintf(stderr, "Error opening file %s\n", argv[1]);
		exit(1);
	}
	p12 = d2i_PKCS12_fp(fp, NULL);
	fclose (fp);
	if (!p12) {
		fprintf(stderr, "Error reading PKCS#12 file\n");
		ERR_print_errors_fp(stderr);
		exit (1);
	}
	if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) {
		fprintf(stderr, "Error parsing PKCS#12 file\n");
		ERR_print_errors_fp(stderr);
		exit (1);
	}
	PKCS12_free(p12);
	if (!(fp = fopen(argv[3], "w"))) {
		fprintf(stderr, "Error opening file %s\n", argv[1]);
		exit(1);
	}
	if (pkey) {
		fprintf(fp, "***Private Key***\n");
		PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
	}
	if (cert) {
		fprintf(fp, "***User Certificate***\n");
		PEM_write_X509_AUX(fp, cert);
	}
	if (ca && sk_X509_num(ca)) {
		fprintf(fp, "***Other Certificates***\n");
		for (i = 0; i < sk_X509_num(ca); i++) 
		    PEM_write_X509_AUX(fp, sk_X509_value(ca, i));
	}
	fclose(fp);
	return 0;
}
Ejemplo n.º 6
0
static int loadPkcs12( const char *fn, const char* pw)
{
    /* you are lost in a maze of twisty crypto algorithms... */
    PKCS12 *p12;
    X509 *x509;
    EVP_PKEY *pkey;
    FILE *fp;
    int ret;
    fp = fopen(fn, "r");
    if (fp == NULL) {
        printf("Could not open file `%s\n", fn);
        return -1;
    }

    p12 = d2i_PKCS12_fp(fp, NULL);

    fclose(fp);

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

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

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

    if (ret != 1) {
        printf("Error parsing certificate (incorrect password?): %s\n", 
                ERR_reason_error_string(ERR_get_error()));
        return -1;
    }
    return 0;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
/* ChangePasswordPKCS12() returns:
 * -1 Wrong password
 * 0  Changing password failed for unknown reason
 * 1  Password changed successfully
 */
int ChangePasswordPKCS12(HWND hwndDlg)
{
  char keyfile[MAX_PATH];
  char oldpsw[50];
  char newpsw[50];
  WCHAR oldpsw_unicode[50];
  WCHAR newpsw_unicode[50];
  FILE *fp;

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

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

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

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

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

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

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

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

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

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

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

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

  return(1);
}
Ejemplo n.º 9
0
static
int cert_stuff(struct connectdata *conn,
               SSL_CTX* ctx,
               char *cert_file,
               const char *cert_type,
               char *key_file,
               const char *key_type)
{
  struct SessionHandle *data = conn->data;
  int file_type;

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

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

    file_type = do_file_type(cert_type);

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

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

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

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

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

      PKCS12_PBE_add();

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

      PKCS12_free(p12);

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

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

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

    file_type = do_file_type(key_type);

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

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

    x509=SSL_get_certificate(ssl);

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

    SSL_free(ssl);

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


    /* Now we know that a key and cert have been set against
     * the SSL context */
    if(!SSL_CTX_check_private_key(ctx)) {
      failf(data, "Private key does not match the certificate public key");
      return(0);
    }
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
    /* erase it now */
    memset(global_passwd, 0, sizeof(global_passwd));
#endif
  }
  return(1);
}
Ejemplo n.º 10
0
apn_return apn_ssl_connect(apn_ctx_t *const ctx) {
    assert(ctx);

    SSL_CTX *ssl_ctx = NULL;
    if (NULL == (ssl_ctx = SSL_CTX_new(TLSv1_client_method()))) {
        apn_log(ctx, APN_LOG_LEVEL_ERROR, "Could not initialize SSL context: %s",
                  ERR_error_string(ERR_get_error(), NULL));
        return APN_ERROR;
    }

    SSL_CTX_set_ex_data(ssl_ctx, 0, ctx);
    SSL_CTX_set_info_callback(ssl_ctx, __apn_ssl_info_callback);

    X509 *cert = NULL;

    if (ctx->pkcs12_file && ctx->pkcs12_pass) {
        FILE *pkcs12_file = NULL;
#ifdef _WIN32
        fopen_s(&pkcs12_file, ctx->pkcs12_file, "r");
#else
        pkcs12_file = fopen(ctx->pkcs12_file, "r");
#endif
        if (!pkcs12_file) {
            char *error = apn_error_string(errno);
            apn_log(ctx, APN_LOG_LEVEL_ERROR, "Unable to open file %s: %s (errno: %d)", ctx->pkcs12_file, error,
                      errno);
            free(error);
            SSL_CTX_free(ssl_ctx);
            errno = APN_ERR_UNABLE_TO_USE_SPECIFIED_PKCS12;
            return APN_ERROR;
        }

        PKCS12 *pkcs12_cert = NULL;
        d2i_PKCS12_fp(pkcs12_file, &pkcs12_cert);
        fclose(pkcs12_file);

        EVP_PKEY *private_key = NULL;

        if (!PKCS12_parse(pkcs12_cert, ctx->pkcs12_pass, &private_key, &cert, NULL)) {
            apn_log(ctx, APN_LOG_LEVEL_ERROR, "Unable to use specified PKCS#12 file: %s",
                      ERR_error_string(ERR_get_error(), NULL));
            PKCS12_free(pkcs12_cert);
            SSL_CTX_free(ssl_ctx);
            errno = APN_ERR_UNABLE_TO_USE_SPECIFIED_PKCS12;
            return APN_ERROR;
        }
        PKCS12_free(pkcs12_cert);

        if (!SSL_CTX_use_certificate(ssl_ctx, cert)) {
            apn_log(ctx, APN_LOG_LEVEL_ERROR, "Unable to use specified PKCS#12 file: %s",
                      ERR_error_string(ERR_get_error(), NULL));
            X509_free(cert);
            EVP_PKEY_free(private_key);
            SSL_CTX_free(ssl_ctx);
            errno = APN_ERR_UNABLE_TO_USE_SPECIFIED_PKCS12;
            return APN_ERROR;
        }

        if (!SSL_CTX_use_PrivateKey(ssl_ctx, private_key)) {
            apn_log(ctx, APN_LOG_LEVEL_ERROR, "Unable to use specified PKCS#12 file: %s",
                      ERR_error_string(ERR_get_error(), NULL));
            X509_free(cert);
            EVP_PKEY_free(private_key);
            SSL_CTX_free(ssl_ctx);
            errno = APN_ERR_UNABLE_TO_USE_SPECIFIED_PKCS12;
            return APN_ERROR;
        }
        EVP_PKEY_free(private_key);
    } else {
        FILE *cert_file = NULL;
#ifdef _WIN32
        fopen_s(&cert_file, ctx->certificate_file, "r");
#else
        cert_file = fopen(ctx->certificate_file, "r");
#endif
        if (!cert_file) {
            char *error = apn_error_string(errno);
            apn_log(ctx, APN_LOG_LEVEL_ERROR, "Unable to open file %s: %s (errno: %d)", ctx->pkcs12_file, error,
                      errno);
            free(error);
            X509_free(cert);
            SSL_CTX_free(ssl_ctx);
            errno = APN_ERR_UNABLE_TO_USE_SPECIFIED_CERTIFICATE;
            return APN_ERROR;
        }

        cert = PEM_read_X509(cert_file, NULL, NULL, NULL);
        if (!cert) {
            apn_log(ctx, APN_LOG_LEVEL_ERROR, "Unable to use specified certificate: %s",
                      ERR_error_string(ERR_get_error(), NULL));
            SSL_CTX_free(ssl_ctx);
            fclose(cert_file);
            errno = APN_ERR_UNABLE_TO_USE_SPECIFIED_CERTIFICATE;
            return EXIT_FAILURE;
        }
        fclose(cert_file);

        if (!SSL_CTX_use_certificate(ssl_ctx, cert)) {
            apn_log(ctx, APN_LOG_LEVEL_ERROR, "Unable to use specified certificate: %s",
                      ERR_error_string(ERR_get_error(), NULL));
            X509_free(cert);
            SSL_CTX_free(ssl_ctx);
            errno = APN_ERR_UNABLE_TO_USE_SPECIFIED_CERTIFICATE;
            return APN_ERROR;
        }

        SSL_CTX_set_default_passwd_cb(ssl_ctx, __apn_ssl_password_callback);
        char *password = NULL;
        if (ctx->private_key_pass) {
            password = apn_strndup(ctx->private_key_pass, strlen(ctx->private_key_pass));
            if (!password) {
                X509_free(cert);
                SSL_CTX_free(ssl_ctx);
                return APN_ERROR;
            }
            SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, password);
        } else {
            SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, NULL);
        }

        if (!SSL_CTX_use_PrivateKey_file(ssl_ctx, ctx->private_key_file, SSL_FILETYPE_PEM)) {
            apn_log(ctx, APN_LOG_LEVEL_ERROR, "Unable to use specified private key: %s",
                      ERR_error_string(ERR_get_error(), NULL));
            apn_strfree(&password);
            X509_free(cert);
            SSL_CTX_free(ssl_ctx);
            errno = APN_ERR_UNABLE_TO_USE_SPECIFIED_PRIVATE_KEY;
            return APN_ERROR;
        }

        apn_strfree(&password);

        if (!SSL_CTX_check_private_key(ssl_ctx)) {
            apn_log(ctx, APN_LOG_LEVEL_ERROR, "Unable to use specified private key: %s",
                      ERR_error_string(ERR_get_error(), NULL));
            errno = APN_ERR_UNABLE_TO_USE_SPECIFIED_PRIVATE_KEY;
            X509_free(cert);
            SSL_CTX_free(ssl_ctx);
            return APN_ERROR;
        }
    }

    if(cert) {
        char *subject = __apn_cert_subject_string(cert);
        apn_log(ctx, APN_LOG_LEVEL_INFO, "Local certificate subject: %s", subject);

        char *issuer = __apn_cert_issuer_string(cert);
        apn_log(ctx, APN_LOG_LEVEL_INFO, "Local certificate issuer: %s", issuer);

        free(subject);
        free(issuer);

        char *cn = __apn_cert_subject_value_by_nib(cert, __APN_X509_ENTRY_CN);
        X509_free(cert);
        if(cn) {
            uint8_t invalid_cert = 0;
            if(apn_mode(ctx) == APN_MODE_PRODUCTION && 0 != strncmp("Apple Production", cn, 16)) {
                invalid_cert = 1;
                apn_log(ctx, APN_LOG_LEVEL_ERROR, "Invalid certificate. You are using a PRODUCTION mode, but certificate was created for usage in SANDBOX");
            } else if (apn_mode(ctx) == APN_MODE_SANDBOX && 0 != strncmp("Apple Development", cn, 17)) {
                invalid_cert = 1;
                apn_log(ctx, APN_LOG_LEVEL_ERROR, "Invalid certificate. You are using a SANDBOX mode, but certificate was created for usage in PRODUCTION");
            }
            free(cn);
            if(1 == invalid_cert) {
                SSL_CTX_free(ssl_ctx);
                errno = APN_ERR_UNABLE_TO_USE_SPECIFIED_CERTIFICATE;
                return APN_ERROR;
            }
        }
    }

    ctx->ssl = SSL_new(ssl_ctx);
    SSL_CTX_free(ssl_ctx);

    if (!ctx->ssl) {
        apn_log(ctx, APN_LOG_LEVEL_ERROR, "Could not initialize SSL");
        errno = APN_ERR_UNABLE_TO_ESTABLISH_SSL_CONNECTION;
        return APN_ERROR;
    }

    int ret = 0;

    if (-1 == (ret = SSL_set_fd(ctx->ssl, ctx->sock))) {
        apn_log(ctx, APN_LOG_LEVEL_ERROR, "Unable to attach socket to SSL: SSL_set_fd() failed (%d)",
                  SSL_get_error(ctx->ssl, ret));
        errno = APN_ERR_UNABLE_TO_ESTABLISH_SSL_CONNECTION;
        return APN_ERROR;
    }

    if (1 > (ret = SSL_connect(ctx->ssl))) {
        char *error = apn_error_string(errno);
        apn_log(ctx, APN_LOG_LEVEL_ERROR,
                  "Could not initialize SSL connection: SSL_connect() failed: %s, %s (errno: %d):",
                  ERR_error_string((unsigned long) SSL_get_error(ctx->ssl, ret), NULL), error, errno);
        free(error);
        return APN_ERROR;
    }
    apn_log(ctx, APN_LOG_LEVEL_INFO, "SSL connection has been established");

    X509 *remote_cert = SSL_get_peer_certificate(ctx->ssl);
    if (remote_cert) {
        char *subject = __apn_cert_subject_string(remote_cert);
        apn_log(ctx, APN_LOG_LEVEL_INFO, "Remote certificate subject: %s", subject);

        char *issuer = __apn_cert_issuer_string(remote_cert);
        apn_log(ctx, APN_LOG_LEVEL_INFO, "Remote certificate issuer: %s", issuer);

        free(subject);
        free(issuer);
        X509_free(remote_cert);
    }
    return APN_SUCCESS;
}
Ejemplo n.º 11
0
static int
sign_with_p12_key(const struct http_io_conf *const config, char *key_file,
		  const char *pwd, char *plain_text, char *signed_buf, size_t buflen)
{
    unsigned char hash[SHA256_DIGEST_LENGTH];
    unsigned char sign[256];
    unsigned int sign_len = 0;
    FILE *fp = NULL;
    PKCS12 *p12 = NULL;
    EVP_PKEY *pkey = NULL;
    X509 *x509 = NULL;
    EVP_MD_CTX *ctx = NULL;
    RSA *prikey = NULL;
    SHA256_CTX sha256;
    const char *c;
    int ret;

    memset(hash, 0, SHA256_DIGEST_LENGTH);
    memset(sign, 0, 256);

    if (!(fp = fopen(key_file, "rb"))){        
        (*config->log)(LOG_ERR, "Error opening cert file %s: %s",
		       key_file, strerror(errno));
	return 1;
    }

    p12 = d2i_PKCS12_fp(fp, NULL);
    fclose(fp);

    if (!p12) {
        (*config->log)(LOG_ERR, "Error reading PKCS#12 file: %s",
		       strerror(errno));
	return 1;
    }

    STACK_OF(X509) *ca = NULL;
    ret = PKCS12_parse(p12, pwd, &pkey, &x509, &ca);
    PKCS12_free(p12);

    if (ret == 0) {
        (*config->log)(LOG_ERR, "Error parsing PKCS#12 file: %s",
		       strerror(errno));
	return 1;
    }

    sign_len = EVP_PKEY_size(pkey);
    ctx = EVP_MD_CTX_create();
    EVP_MD_CTX_init(ctx);

    prikey = EVP_PKEY_get1_RSA(pkey);

    SHA256_Init(&sha256);
    c = plain_text;
    SHA256_Update(&sha256, c, strlen(c));
    SHA256_Final(hash, &sha256);
      
    ret = RSA_sign(NID_sha256, hash, SHA256_DIGEST_LENGTH, sign,  &sign_len, prikey);
    EVP_MD_CTX_destroy(ctx);
    RSA_free(prikey);
    EVP_PKEY_free(pkey);
    X509_free(x509);

    if (ret == 0) {
        (*config->log)(LOG_ERR, "Signing p12 key with RSA Signature failed ");
	return 1;
    }
   
    memset(signed_buf, 0, buflen);
    http_io_base64_encode_safe(signed_buf, buflen, sign, sign_len);

    return 0;
}
Ejemplo n.º 12
0
char * PKCS7_GetSign(char*certFile,char* pwd, char* plainText,int flag)  
{  
    //取PKCS12對象  
    FILE* fp;  
    if (!(fp = fopen(certFile, "rb")))   
    {   
        fprintf(stderr, "Error opening file %s\n", certFile);          
        return NULL;       
    }      
    PKCS12 *p12= d2i_PKCS12_fp(fp, NULL);    
    fclose (fp);      
    if (!p12) {        
        fprintf(stderr, "Error reading PKCS#12 file\n");     
        ERR_print_errors_fp(stderr);    
        return NULL;     
    }   
       
    //取pkey對象、X509證書、證書鏈  
    EVP_PKEY *pkey=NULL;       
    X509 *x509=NULL;  
    STACK_OF(X509) *ca = NULL;  
    if (!PKCS12_parse(p12, pwd, &pkey, &x509, &ca)) {           
        fprintf(stderr, "Error parsing PKCS#12 file\n");         
        ERR_print_errors_fp(stderr);  
        return NULL;  
    }   
    PKCS12_free(p12);  
  
    //明文轉為BIO對象  
    //《vc++网络安全编程范例(14)-openssl bio编程 》   http://www.2cto.com/kf/201112/115018.html  
    BIO *bio = BIO_new(BIO_s_mem());    
    BIO_puts(bio,plainText);  
  
    //數字簽名  
    //PKCS7_NOCHAIN:签名中不包含证书链,第三个参数为NULL值的话,可不加这个FLAG标记  
    //PKCS7_NOSMIMECAP:签名不需要支持SMIME  
    PKCS7* pkcs7 = PKCS7_sign(x509,pkey, ca,bio, flag);  
    if(pkcs7==NULL)  
    {  
        ERR_print_errors_fp(stderr);  
        return NULL;  
    }  
  
    //共有两种编码,一种是ASN1,另一种是DER编码。  
    //取數據簽名(DER格式)  
    //openssl学习笔记之pkcs7-data内容类型的编码解码  
    //http://ipedo.i.sohu.com/blog/view/114822358.htm  
    //入口:pkcs7对象  
    //出口:der对象  
    unsigned char *der;  
    unsigned char *derTmp;  
    unsigned long derlen;  
    derlen = i2d_PKCS7(pkcs7,NULL);  
    der = (unsigned char *) malloc(derlen);  
    memset(der,0,derlen);  
    derTmp = der;  
    i2d_PKCS7(pkcs7,&derTmp);  
  
    //DER转BASE64  
    return base64(der,derlen);  
}  
Ejemplo n.º 13
0
/**
 * \fn resultP12ToPem p12ToPem (string, string)
 * \brief Convert P12 to PEM
 * \param string p12File Path to P12 file
 * \param string p12Passwd Password to open P12 file
 * \return result (bool ReturnCode, Int ErrorCode, String Comment, String PrivateKey, String Certificate)
 */
resultP12ToPem p12ToPem(string p12File, string p12Passwd) {
    FILE *fp;
    PKCS12 *p12 = NULL;
    EVP_PKEY *pkey = NULL;
    X509 *cert = NULL;
    STACK_OF(X509) *ca = NULL;
    
    BIO *o = BIO_new(BIO_s_mem());
    
    string privateKey = "";
    string certificate = "";
        
    resultP12ToPem ret;
    ret.ReturnCode = false;
    ret.ErrorCode = 0;
    ret.Comment = "";
    ret.PrivateKey = "";
    ret.Certificate = "";
    
    SSLeay_add_all_algorithms();
    ERR_load_crypto_strings();
    if(!(fp = fopen(p12File.c_str(), "rb"))) {
        ret.ErrorCode = 1;
        ret.Comment = strerror(errno);
        return ret;
    }
    
    p12 = d2i_PKCS12_fp(fp, &p12);
    fclose (fp);
    
    if (!p12) {
        ret.ErrorCode = 2;
        ret.Comment = "Unable to open PKCS#12 file";
        return ret;
    }
    if (!PKCS12_parse(p12, p12Passwd.c_str(), &pkey, &cert, &ca)) {
        ret.ErrorCode = 3;
        ret.Comment = "Unable to parse PKCS#12 file (wrong password ?)";
        return ret;
    }
    PKCS12_free(p12);
    
    if (!(pkey && cert)) {
        ret.ErrorCode = 4;
        ret.Comment = "Certificate and/or key file doesn't exists";
    } else {
        PEM_write_bio_PrivateKey(o, pkey, 0, 0, 0, NULL, 0);
        privateKey = x509ToString(o);
                
        PEM_write_bio_X509(o, cert);
        certificate = x509ToString(o);
        
        BIO_free(o);
        
        ret.ReturnCode = true;
        ret.ErrorCode = 0;
        ret.Comment = "All is fine";
        ret.PrivateKey = privateKey;
        ret.Certificate = certificate;
    }
    return ret;
}
Ejemplo n.º 14
0
static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key,
			   const char *passwd)
{
#ifdef PKCS12_FUNCS
	FILE *f;
	PKCS12 *p12;
	EVP_PKEY *pkey;
	X509 *cert;
	int res = 0;

	f = fopen(private_key, "r");
	if (f == NULL)
		return -1;

	p12 = d2i_PKCS12_fp(f, NULL);
	if (p12 == NULL) {
		wpa_printf(MSG_DEBUG, "TLS: Failed to read PKCS12 file '%s'",
			   private_key);
		fclose(f);
		return -1;
	}
	fclose(f);

	pkey = NULL;
	cert = NULL;
	if (!PKCS12_parse(p12, passwd, &pkey, &cert, NULL)) {
		wpa_printf(MSG_DEBUG, "TLS: Failed to parse PKCS12 file '%s': "
			   "%s", private_key,
			   ERR_error_string(ERR_get_error(), NULL));
		return -1;
	}
	wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 file '%s'",
		   private_key);

	if (cert) {
		wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12");
		if (ssl) {
			if (SSL_use_certificate(ssl, cert) != 1)
				res = -1;
		} else {
			if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1)
				res = -1;
		}
		X509_free(cert);
	}

	if (pkey) {
		wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12");
		if (ssl) {
			if (SSL_use_PrivateKey(ssl, pkey) != 1)
				res = -1;
		} else {
			if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1)
				res = -1;
		}
		EVP_PKEY_free(pkey);
	}

	PKCS12_free(p12);

	return res;
#else /* PKCS12_FUNCS */
	wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read "
		   "p12/pfx files");
	return -1;
#endif  /* PKCS12_FUNCS */
}
Ejemplo n.º 15
0
int
main(int argc, char **argv) {
  FILE           *fp   = NULL;
  EVP_PKEY       *pkey = NULL;
  X509           *cert = NULL;
  STACK_OF(X509) *ca   = NULL;
  PKCS12         *p12  = NULL;

  char *pass = strdup("");
  int  i;

  if (argc != 2) {
    fprintf(stderr, "[!] Usage: %s certificate.p12\n", argv[0]);
    exit(1);
  }

  printf("[+] Initializing OpenSSL\n");
  SSLeay_add_all_algorithms();
  ERR_load_crypto_strings();

  printf("[+] Opening PKCS#12 certificate\n");
  if (!(fp = fopen(argv[1], "r"))) {
    fprintf(stderr, "[!] Unable to open certificate `%s'\n", argv[1]);
    goto endpkcs12;
  }

  if (chdir(dirname(argv[1])) == -1) {
    fprintf(stderr, "[!] Unable to change directory to `%s'\n",
	    dirname(argv[1]));
    goto endpkcs12;
  }
  p12 = d2i_PKCS12_fp(fp, NULL);
  fclose(fp); fp = NULL;
  if (!p12) {
    fprintf(stderr, "[!] Unable to parse PKCS#12 certificate: %s\n",
	    ERR_reason_error_string(ERR_get_error()));
    goto endpkcs12;
  }
  while (!PKCS12_parse(p12, pass, &pkey, &cert, &ca)) {
    ca = NULL;
    free(pass);
    if (getpassword("[?] Password: "******"[!] PKCS#12 certificate is incomplete\n");
    goto endpkcs12;
  }

#define PEM_w(path, call) \
  do {									\
    if (!(fp = fopen(path, "w"))) {					\
      fprintf(stderr, "[!] Unable to open `%s'\n", path);		\
      goto endpkcs12;							\
    }									\
    printf("[+] Write certificate to `%s'\n", path);			\
    call;								\
    fclose(fp); fp = NULL;						\
  } while(0)
    
  PEM_w("user.pem", PEM_write_X509(fp, cert));
  PEM_w("user.key",  PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL));
  PEM_w("cacert.pem",
	for (i = 0; i < sk_X509_num(ca); i++)
	  PEM_write_X509(fp, sk_X509_value(ca, i)));
  sk_free(ca); X509_free(cert); EVP_PKEY_free(pkey);
  exit(0);

 endpkcs12:
  if (pass) free(pass);
  if (ca) sk_free(ca);
  if (cert) X509_free(cert);
  if (pkey) EVP_PKEY_free(pkey);
  if (p12) PKCS12_free(p12);
  if (fp) fclose(fp);
  exit(1);
}
Ejemplo n.º 16
0
static int load_certificate(struct openconnect_info *vpninfo)
{
	if (!strncmp(vpninfo->sslkey, "pkcs11:", 7) ||
	    !strncmp(vpninfo->cert, "pkcs11:", 7)) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("This binary built without PKCS#11 support\n"));
		return -EINVAL;
	}

	vpn_progress(vpninfo, PRG_TRACE,
		     _("Using certificate file %s\n"), vpninfo->cert);

	if (strncmp(vpninfo->cert, "keystore:", 9) &&
	    (vpninfo->cert_type == CERT_TYPE_PKCS12 ||
	     vpninfo->cert_type == CERT_TYPE_UNKNOWN)) {
		FILE *f;
		PKCS12 *p12;

		f = fopen(vpninfo->cert, "r");
		if (!f) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to open certificate file %s: %s\n"),
				     vpninfo->cert, strerror(errno));
			return -ENOENT;
		}
		p12 = d2i_PKCS12_fp(f, NULL);
		fclose(f);
		if (p12)
			return load_pkcs12_certificate(vpninfo, p12);

		/* Not PKCS#12 */
		if (vpninfo->cert_type == CERT_TYPE_PKCS12) {
			vpn_progress(vpninfo, PRG_ERR, _("Read PKCS#12 failed\n"));
			openconnect_report_ssl_errors(vpninfo);
			return -EINVAL;
		}
		/* Clear error and fall through to see if it's a PEM file... */
		ERR_clear_error();
	}

	/* It's PEM or TPM now, and either way we need to load the plain cert: */
#ifdef ANDROID_KEYSTORE
	if (!strncmp(vpninfo->cert, "keystore:", 9)) {
		BIO *b = BIO_from_keystore(vpninfo, vpninfo->cert);
		if (!b)
			return -EINVAL;
		vpninfo->cert_x509 = PEM_read_bio_X509_AUX(b, NULL, pem_pw_cb, vpninfo);
		BIO_free(b);
		if (!vpninfo->cert_x509) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to load X509 certificate from keystore\n"));
			openconnect_report_ssl_errors(vpninfo);
			return -EINVAL;
		}
		if (!SSL_CTX_use_certificate(vpninfo->https_ctx, vpninfo->cert_x509)) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to use X509 certificate from keystore\n"));
			openconnect_report_ssl_errors(vpninfo);
			X509_free(vpninfo->cert_x509);
			vpninfo->cert_x509 = NULL;
			return -EINVAL;
		}
	} else
#endif /* ANDROID_KEYSTORE */
	{
		if (!SSL_CTX_use_certificate_chain_file(vpninfo->https_ctx,
							vpninfo->cert)) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Loading certificate failed\n"));
			openconnect_report_ssl_errors(vpninfo);
			return -EINVAL;
		}

		/* Ew, we can't get it back from the OpenSSL CTX in any sane fashion */
		reload_pem_cert(vpninfo);
	}

#ifdef ANDROID_KEYSTORE
	if (!strncmp(vpninfo->sslkey, "keystore:", 9)) {
		EVP_PKEY *key;
		BIO *b;

	again_android:
		b = BIO_from_keystore(vpninfo, vpninfo->sslkey);
		if (!b)
			return -EINVAL;
		key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, vpninfo);
		BIO_free(b);
		if (!key) {
			if (is_pem_password_error(vpninfo))
				goto again_android;
			return -EINVAL;
		}
		if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to use private key from keystore\n"));
			EVP_PKEY_free(key);
			X509_free(vpninfo->cert_x509);
			vpninfo->cert_x509 = NULL;
			return -EINVAL;
		}
		return 0;
	}
#endif /* ANDROID_KEYSTORE */

	if (vpninfo->cert_type == CERT_TYPE_UNKNOWN) {
		FILE *f = fopen(vpninfo->sslkey, "r");
		char buf[256];

		if (!f) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to open private key file %s: %s\n"),
				     vpninfo->cert, strerror(errno));
			return -ENOENT;
		}

		buf[255] = 0;
		while (fgets(buf, 255, f)) {
			if (!strcmp(buf, "-----BEGIN TSS KEY BLOB-----\n")) {
				vpninfo->cert_type = CERT_TYPE_TPM;
				break;
			} else if (!strcmp(buf, "-----BEGIN RSA PRIVATE KEY-----\n") ||
				   !strcmp(buf, "-----BEGIN DSA PRIVATE KEY-----\n") ||
				   !strcmp(buf, "-----BEGIN ENCRYPTED PRIVATE KEY-----\n")) {
				vpninfo->cert_type = CERT_TYPE_PEM;
				break;
			}
		}
		fclose(f);
		if (vpninfo->cert_type == CERT_TYPE_UNKNOWN) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to identify private key type in '%s'\n"),
				     vpninfo->sslkey);
			return -EINVAL;
		}
	}

	if (vpninfo->cert_type == CERT_TYPE_TPM)
		return load_tpm_certificate(vpninfo);

	/* Standard PEM certificate */
	SSL_CTX_set_default_passwd_cb(vpninfo->https_ctx, pem_pw_cb);
	SSL_CTX_set_default_passwd_cb_userdata(vpninfo->https_ctx, vpninfo);
 again:
	if (!SSL_CTX_use_RSAPrivateKey_file(vpninfo->https_ctx, vpninfo->sslkey,
					    SSL_FILETYPE_PEM)) {
		if (is_pem_password_error(vpninfo))
			goto again;
		return -EINVAL;
	}
	return 0;
}
Ejemplo n.º 17
0
int main(int argc, char **argv)
{
    FILE *fp;
    EVP_PKEY *pkey = NULL;
    X509 *cert = NULL;
    STACK_OF(X509) *ca = NULL;
    PKCS12 *p12 = NULL;
    char *name = NULL;
    int i, ret = EXIT_FAILURE;

    if (argc != 4) {
        fprintf(stderr, "Usage: pkread p12file password opfile\n");
        exit(EXIT_FAILURE);
    }

    if ((fp = fopen(argv[1], "rb")) == NULL) {
        fprintf(stderr, "Error opening file %s\n", argv[1]);
        exit(EXIT_FAILURE);
    }
    p12 = d2i_PKCS12_fp(fp, NULL);
    fclose(fp);
    if (p12 == NULL) {
        fprintf(stderr, "Error reading PKCS#12 file\n");
        ERR_print_errors_fp(stderr);
        goto err;
    }
    if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) {
        fprintf(stderr, "Error parsing PKCS#12 file\n");
        ERR_print_errors_fp(stderr);
        goto err;
    }
    name = find_friendly_name(p12);
    PKCS12_free(p12);
    if ((fp = fopen(argv[3], "w")) == NULL) {
        fprintf(stderr, "Error opening file %s\n", argv[1]);
        goto err;
    }
    if (name != NULL)
        fprintf(fp, "***Friendly Name***\n%s\n", name);
    if (pkey != NULL) {
        fprintf(fp, "***Private Key***\n");
        PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
    }
    if (cert != NULL) {
        fprintf(fp, "***User Certificate***\n");
        PEM_write_X509_AUX(fp, cert);
    }
    if (ca != NULL && sk_X509_num(ca) > 0) {
        fprintf(fp, "***Other Certificates***\n");
        for (i = 0; i < sk_X509_num(ca); i++)
            PEM_write_X509_AUX(fp, sk_X509_value(ca, i));
    }
    fclose(fp);

    ret = EXIT_SUCCESS;

 err:
    OPENSSL_free(name);
    X509_free(cert);
    EVP_PKEY_free(pkey);
    sk_X509_pop_free(ca, X509_free);

    return ret;
}