RSA* key_from_bio(BIO *key_bio, BOOL is_private) { EVP_PKEY *pkey = NULL; if(is_private) { pkey = PEM_read_bio_PrivateKey(key_bio, NULL,NULL, NULL); }else { pkey = PEM_read_bio_PUBKEY(key_bio, NULL, NULL, NULL); } if(!pkey) { fprintf(stderr, "ERROR: key read from BIO is null\n"); exit(1); } BIO_free(key_bio); RSA *rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); return rsa; }
static int cryptoMagic(X509 *x0, X509 *x1, X509 *x2, const unsigned char *toHashData, int toHashLength, /*XXX const*/ unsigned char *rsaSigData, int rsaSigLen, DataValue *partialDigest) { int rv = 0; EVP_PKEY *pk = X509_get_pubkey(x2); if (pk) { if (pk->type == EVP_PKEY_RSA) { RSA *rsa = EVP_PKEY_get1_RSA(pk); if (rsa) { X509_STORE *store = X509_STORE_new(); if (store) { X509_STORE_CTX ctx; X509_STORE_add_cert(store, x0); X509_STORE_add_cert(store, x1); if (X509_STORE_CTX_init(&ctx, store, x2, 0) == 1) { X509_STORE_CTX_set_flags(&ctx, X509_V_FLAG_IGNORE_CRITICAL); if (X509_verify_cert(&ctx) == 1) { unsigned char md[SHA_DIGEST_LENGTH]; if (partialDigest) { // XXX we need to flip ECID back before hashing flipAppleImg3Header((AppleImg3Header *)toHashData); doPartialSHA1(md, toHashData, toHashLength, partialDigest); } else { SHA1(toHashData, toHashLength, md); } rv = RSA_verify(NID_sha1, md, SHA_DIGEST_LENGTH, rsaSigData, rsaSigLen, rsa); } X509_STORE_CTX_cleanup(&ctx); } X509_STORE_free(store); } RSA_free(rsa); } } EVP_PKEY_free(pk); } return rv ? 0 : -1; }
char *cipher_rsa_decrypt(const char *ciphertext, size_t len, const struct private_key *private_key) { PKCS8_PRIV_KEY_INFO *p8inf = NULL; EVP_PKEY *pkey = NULL; RSA *rsa = NULL; BIO *memory = NULL; char *ret = NULL; if (!len) return NULL; memory = BIO_new(BIO_s_mem()); if (BIO_write(memory, private_key->key, private_key->len) < 0) goto out; p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(memory, NULL); if (!p8inf) goto out; pkey = EVP_PKCS82PKEY(p8inf); if (!pkey) goto out; if (p8inf->broken) goto out; rsa = EVP_PKEY_get1_RSA(pkey); if (!rsa) goto out; ret = xcalloc(len + 1, 1); if (RSA_private_decrypt(len, (unsigned char *)ciphertext, (unsigned char *)ret, rsa, RSA_PKCS1_OAEP_PADDING) < 0) { free(ret); ret = NULL; goto out; } out: PKCS8_PRIV_KEY_INFO_free(p8inf); EVP_PKEY_free(pkey); RSA_free(rsa); BIO_free_all(memory); return ret; }
RSA * d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length) { EVP_PKEY *pkey; RSA *key; const unsigned char *q; q = *pp; pkey = d2i_PUBKEY(NULL, &q, length); if (!pkey) return NULL; key = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); if (!key) return NULL; *pp = q; if (a) { RSA_free(*a); *a = key; } return key; }
PyObject * get_key_pem_private(const struct ccn_pkey *private_key_ccn) { unsigned long err; RSA *private_key_rsa = NULL; BIO *bio; BUF_MEM *bufmem; int r; PyObject *py_res; bio = BIO_new(BIO_s_mem()); JUMP_IF_NULL(bio, openssl_error); private_key_rsa = EVP_PKEY_get1_RSA((EVP_PKEY *) private_key_ccn); JUMP_IF_NULL(private_key_rsa, openssl_error); r = PEM_write_bio_RSAPrivateKey(bio, private_key_rsa, NULL, NULL, 0, NULL, NULL); RSA_free(private_key_rsa); private_key_rsa = NULL; if (!r) goto openssl_error; BIO_get_mem_ptr(bio, &bufmem); py_res = PyBytes_FromStringAndSize(bufmem->data, bufmem->length); r = BIO_free(bio); if (!r) goto openssl_error; return py_res; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_CCNKeyError, "Unable to obtain PEM: %s", ERR_reason_error_string(err)); RSA_free(private_key_rsa); BIO_free(bio); return NULL; }
void * wi_socket_ssl_pubkey(wi_socket_t *socket) { #ifdef WI_SSL RSA *rsa = NULL; X509 *x509 = NULL; EVP_PKEY *pkey = NULL; x509 = SSL_get_peer_certificate(socket->ssl); if(!x509) { wi_error_set_ssl_error(); goto end; } pkey = X509_get_pubkey(x509); if(!pkey) { wi_error_set_ssl_error(); goto end; } rsa = EVP_PKEY_get1_RSA(pkey); if(!rsa) wi_error_set_ssl_error(); end: if(x509) X509_free(x509); if(pkey) EVP_PKEY_free(pkey); return rsa; #else return NULL; #endif }
int GetRSAKey(RSA **rsa, /* freed by caller */ X509 *x509Certificate) { int rc = 0; EVP_PKEY *pkey = NULL; if (rc == 0) { pkey = X509_get_pubkey(x509Certificate); if (pkey == NULL) { printf("Error: Cannot get certificate public key\n"); rc = -1; } } if (rc == 0) { *rsa = EVP_PKEY_get1_RSA(pkey); if (*rsa == NULL) { printf("Error: Cannot extract certificate RSA public key\n"); rc = -1; } } return rc; }
wi_rsa_t * wi_socket_ssl_public_key(wi_socket_t *socket) { #ifdef HAVE_OPENSSL_SSL_H RSA *rsa = NULL; X509 *x509 = NULL; EVP_PKEY *pkey = NULL; x509 = SSL_get_peer_certificate(socket->ssl); if(!x509) { wi_error_set_openssl_error(); goto end; } pkey = X509_get_pubkey(x509); if(!pkey) { wi_error_set_openssl_error(); goto end; } rsa = EVP_PKEY_get1_RSA(pkey); if(!rsa) wi_error_set_openssl_error(); end: if(x509) X509_free(x509); if(pkey) EVP_PKEY_free(pkey); return wi_autorelease(wi_rsa_init_with_rsa(wi_rsa_alloc(), rsa)); #else return NULL; #endif }
static int verify_rsa(EVP_PKEY* pkey, keymaster_rsa_sign_params_t* sign_params, const uint8_t* signedData, const size_t signedDataLength, const uint8_t* signature, const size_t signatureLength) { if (sign_params->digest_type != DIGEST_NONE) { ALOGW("Cannot handle digest type %d", sign_params->digest_type); return -1; } else if (sign_params->padding_type != PADDING_NONE) { ALOGW("Cannot handle padding type %d", sign_params->padding_type); return -1; } else if (signatureLength != signedDataLength) { ALOGW("signed data length must be signature length"); return -1; } Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey)); if (rsa.get() == NULL) { logOpenSSLError("openssl_verify_data"); return -1; } UniquePtr<uint8_t[]> dataPtr(new uint8_t[signedDataLength]); if (dataPtr.get() == NULL) { logOpenSSLError("openssl_verify_data"); return -1; } unsigned char* tmp = reinterpret_cast<unsigned char*>(dataPtr.get()); if (!RSA_public_decrypt(signatureLength, signature, tmp, rsa.get(), RSA_NO_PADDING)) { logOpenSSLError("openssl_verify_data"); return -1; } int result = 0; for (size_t i = 0; i < signedDataLength; i++) { result |= tmp[i] ^ signedData[i]; } return result == 0 ? 0 : -1; }
SEXP PKI_verify_RSA(SEXP what, SEXP sMD, SEXP sKey, SEXP sig) { int md = asInteger(sMD), type; EVP_PKEY *key; RSA *rsa; switch (md) { case PKI_MD5: type = NID_md5; break; case PKI_SHA1: type = NID_sha1; break; case PKI_SHA256: type = NID_sha256; break; default: Rf_error("unsupported hash type"); } if (TYPEOF(what) != RAWSXP || (md == PKI_MD5 && LENGTH(what) != MD5_DIGEST_LENGTH) || (md == PKI_SHA1 && LENGTH(what) != SHA_DIGEST_LENGTH) || (md == PKI_SHA256 && LENGTH(what) != SHA256_DIGEST_LENGTH)) Rf_error("invalid hash"); if (!inherits(sKey, "public.key") && !inherits(sKey, "private.key")) Rf_error("key must be RSA public or private key"); key = (EVP_PKEY*) R_ExternalPtrAddr(sKey); if (!key) Rf_error("NULL key"); if (EVP_PKEY_type(key->type) != EVP_PKEY_RSA) Rf_error("key must be RSA public or private key"); rsa = EVP_PKEY_get1_RSA(key); if (!rsa) Rf_error("%s", ERR_error_string(ERR_get_error(), NULL)); return ScalarLogical( /* FIXME: sig is not const in RSA_verify - that is odd so in theory in may modify sig ... */ (RSA_verify(type, (const unsigned char*) RAW(what), LENGTH(what), (unsigned char *) RAW(sig), LENGTH(sig), rsa) == 1) ? TRUE : FALSE); }
static struct ndn_keystore* Key_to_ndn_keystore(PyObject* py_key) { // An imperfect conversion here, but... // This is supposed to be an opaque type. // We borrow this from ndn_keystore.c // so that we can work with the ndn hashtable // and do Key_to_keystore... but this whole method may not be // ever needed, as the ndn_keystore type seems // to be primarily for the use of the library internally? struct ndn_keystore_private { int initialized; EVP_PKEY *private_key; EVP_PKEY *public_key; X509 *certificate; ssize_t pubkey_digest_length; unsigned char pubkey_digest[SHA256_DIGEST_LENGTH]; }; struct ndn_keystore_private* keystore = calloc(1, sizeof(struct ndn_keystore_private)); keystore->initialized = 1; // TODO: need to INCREF here? keystore->private_key = (EVP_PKEY*) PyCObject_AsVoidPtr(PyObject_GetAttrString(py_key, "ndn_data_private")); keystore->public_key = (EVP_PKEY*) PyCObject_AsVoidPtr(PyObject_GetAttrString(py_key, "ndn_data_public")); RSA* private_key_rsa = EVP_PKEY_get1_RSA((EVP_PKEY*) keystore->private_key); unsigned char* public_key_digest; size_t public_key_digest_len; create_public_key_digest(private_key_rsa, &public_key_digest, &public_key_digest_len); memcpy(keystore->pubkey_digest, public_key_digest, public_key_digest_len); keystore->pubkey_digest_length = public_key_digest_len; free(public_key_digest); free(private_key_rsa); return(struct ndn_keystore*) keystore; }
QSslKey SafetPKCS12::keyFromEVP( EVP_PKEY * evp ) { EVP_PKEY *key = (EVP_PKEY*)evp; unsigned char *data = NULL; int len = 0; QSsl::KeyAlgorithm alg; QSsl::KeyType type; switch( EVP_PKEY_type( key->type ) ) { case EVP_PKEY_RSA: { RSA *rsa = EVP_PKEY_get1_RSA( key ); alg = QSsl::Rsa; type = rsa->d ? QSsl::PrivateKey : QSsl::PublicKey; len = rsa->d ? i2d_RSAPrivateKey( rsa, &data ) : i2d_RSAPublicKey( rsa, &data ); RSA_free( rsa ); break; } case EVP_PKEY_DSA: { DSA *dsa = EVP_PKEY_get1_DSA( key ); alg = QSsl::Dsa; type = dsa->priv_key ? QSsl::PrivateKey : QSsl::PublicKey; len = dsa->priv_key ? i2d_DSAPrivateKey( dsa, &data ) : i2d_DSAPublicKey( dsa, &data ); DSA_free( dsa ); break; } default: break; } QSslKey k; if( len > 0 ) k = QSslKey( QByteArray( (char*)data, len ), alg, QSsl::Der, type ); OPENSSL_free( data ); return k; }
int ca_privkey_serialize(EVP_PKEY *key, struct iked_id *id) { RSA *rsa; u_int8_t *d; int len = 0; switch (key->type) { case EVP_PKEY_RSA: id->id_type = 0; id->id_offset = 0; ibuf_release(id->id_buf); if ((rsa = EVP_PKEY_get1_RSA(key)) == NULL) return (-1); if ((len = i2d_RSAPrivateKey(rsa, NULL)) <= 0) return (-1); if ((id->id_buf = ibuf_new(NULL, len)) == NULL) return (-1); d = ibuf_data(id->id_buf); if (i2d_RSAPrivateKey(rsa, &d) != len) { ibuf_release(id->id_buf); return (-1); } id->id_type = IKEV2_CERT_RSA_KEY; break; default: log_debug("%s: unsupported key type %d", __func__, key->type); return (-1); } log_debug("%s: type %s length %d", __func__, print_map(id->id_type, ikev2_cert_map), len); return (0); }
/** * Verify signature with RSA public key from X.509 certificate. * * @param digestMethod digest method (e.g NID_sha1 for SHA1, see openssl/obj_mac.h). * @param digest digest value, this value is compared with the digest value decrypted from the <code>signature</code>. * @param signature signature value, this value is decrypted to get the digest and compared with * the digest value provided in <code>digest</code>. * @return returns <code>true</code> if the signature value matches with the digest, otherwise <code>false</code> * is returned. * @throws IOException throws exception if X.509 certificate is not missing or does not have a RSA public key. */ bool digidoc::RSACrypt::verify(int digestMethod, std::vector<unsigned char> digest, std::vector<unsigned char> signature) throw(IOException) { // Check that X.509 certificate is set. if(cert == NULL) { THROW_IOEXCEPTION("X.509 certificate parameter is not set in RSACrypt, can not verify signature."); } // Extract RSA public key from X.509 certificate. X509Cert x509(cert); EVP_PKEY* key = x509.getPublicKey(); if(EVP_PKEY_type(key->type) != EVP_PKEY_RSA) { EVP_PKEY_free(key); THROW_IOEXCEPTION("Certificate '%s' does not have a RSA public key, can not verify signature.", x509.getSubject().c_str()); } RSA* publicKey = EVP_PKEY_get1_RSA(key); // Verify signature with RSA public key. int result = RSA_verify(digestMethod, &digest[0], digest.size(), &signature[0], signature.size(), publicKey); RSA_free(publicKey); EVP_PKEY_free(key); return (result == 1); }
SEXP PKI_decrypt(SEXP what, SEXP sKey) { SEXP res; EVP_PKEY *key; RSA *rsa; int len; if (TYPEOF(what) != RAWSXP) Rf_error("invalid payload to sign - must be a raw vector"); if (!inherits(sKey, "private.key")) Rf_error("invalid key object"); key = (EVP_PKEY*) R_ExternalPtrAddr(sKey); if (!key) Rf_error("NULL key"); if (EVP_PKEY_type(key->type) != EVP_PKEY_RSA) Rf_error("Sorry only RSA keys are supported at this point"); rsa = EVP_PKEY_get1_RSA(key); if (!rsa) Rf_error("%s", ERR_error_string(ERR_get_error(), NULL)); len = RSA_private_decrypt(LENGTH(what), RAW(what), (unsigned char*) buf, rsa, RSA_PKCS1_PADDING); if (len < 0) Rf_error("%s", ERR_error_string(ERR_get_error(), NULL)); res = allocVector(RAWSXP, len); memcpy(RAW(res), buf, len); return res; }
/* Function to verify a given image and signature. Reference implementation in the Little Kernel source in "platform/msm_shared/image_verify.c" Returns -1 if somethings fails otherwise 0 */ int verify_image(unsigned char *image_ptr, unsigned char *signature_ptr, unsigned int image_size) { X509 *x509_certificate = NULL; EVP_PKEY *pub_key = NULL; RSA *rsa_key = NULL; unsigned char *plain_text = NULL; unsigned char digest[65]; unsigned int hash_size = SHA256_SIZE; int ret = 0; /* Load certificate */ FILE *fcert; fcert = fopen("prodcert.pem", "rb"); if (fcert == NULL){ fclose(fcert); std::cerr << "[ ERROR ] Missing certificate" << std::endl; ret = -1; goto cleanup; } x509_certificate = PEM_read_X509(fcert, NULL, NULL, NULL); fclose(fcert); /* Obtain RSA key */ pub_key = X509_get_pubkey(x509_certificate); rsa_key = EVP_PKEY_get1_RSA(pub_key); if (rsa_key == NULL){ std::cerr << "[ ERROR ] Couldn't obtain key from certificate" << std::endl; ret = -1; goto cleanup; } /* Create buffer for decrypted hash */ plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE); if (plain_text == NULL) { std::cerr << "[ ERROR ] calloc failed during verification" << std::endl; ret = -1; goto cleanup; } /* Decrypt hash */ RSA_public_decrypt(SIGNATURE_SIZE, signature_ptr, plain_text, rsa_key, RSA_PKCS1_PADDING); /* Hash the image */ sha256_buffer(image_ptr, image_size, digest); /* Check if signature is equal to the calculated hash */ if (memcmp(plain_text, digest, hash_size) != 0) { std::cerr << std::endl << "[ ERROR ] Invalid signature" << std::endl; ret = -1; goto cleanup; } else { std::cerr << std::endl << "[ SUCCESS ] The signature is valid!" << std::endl; } /* Cleanup after complete usage of openssl - cached data and objects */ cleanup: if (rsa_key != NULL) RSA_free(rsa_key); if (x509_certificate != NULL) X509_free(x509_certificate); if (pub_key != NULL) EVP_PKEY_free(pub_key); if (plain_text != NULL) free(plain_text); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); return ret; }
int tls_configure_ssl_keypair(struct tls *ctx, SSL_CTX *ssl_ctx, struct tls_keypair *keypair, int required) { EVP_PKEY *pkey = NULL; BIO *bio = NULL; if (!required && keypair->cert_mem == NULL && keypair->key_mem == NULL) return(0); if (keypair->cert_mem != NULL) { if (keypair->cert_len > INT_MAX) { tls_set_errorx(ctx, "certificate too long"); goto err; } if (SSL_CTX_use_certificate_chain_mem(ssl_ctx, keypair->cert_mem, keypair->cert_len) != 1) { tls_set_errorx(ctx, "failed to load certificate"); goto err; } if (tls_keypair_pubkey_hash(keypair, &keypair->pubkey_hash) == -1) goto err; } if (keypair->key_mem != NULL) { if (keypair->key_len > INT_MAX) { tls_set_errorx(ctx, "key too long"); goto err; } if ((bio = BIO_new_mem_buf(keypair->key_mem, keypair->key_len)) == NULL) { tls_set_errorx(ctx, "failed to create buffer"); goto err; } if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, tls_password_cb, NULL)) == NULL) { tls_set_errorx(ctx, "failed to read private key"); goto err; } if (keypair->pubkey_hash != NULL) { RSA *rsa; /* XXX only RSA for now for relayd privsep */ if ((rsa = EVP_PKEY_get1_RSA(pkey)) != NULL) { RSA_set_ex_data(rsa, 0, keypair->pubkey_hash); RSA_free(rsa); } } if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) { tls_set_errorx(ctx, "failed to load private key"); goto err; } BIO_free(bio); bio = NULL; EVP_PKEY_free(pkey); pkey = NULL; } if (!ctx->config->skip_private_key_check && SSL_CTX_check_private_key(ssl_ctx) != 1) { tls_set_errorx(ctx, "private/public key mismatch"); goto err; } return (0); err: EVP_PKEY_free(pkey); BIO_free(bio); return (1); }
/** Generate a new certificate for our loaded or generated keys, and write it * to disk. Return 0 on success, nonzero on failure. */ static int generate_certificate(void) { char buf[8192]; time_t now = time(NULL); struct tm tm; char published[ISO_TIME_LEN+1]; char expires[ISO_TIME_LEN+1]; char id_digest[DIGEST_LEN]; char fingerprint[FINGERPRINT_LEN+1]; char *ident = key_to_string(identity_key); char *signing = key_to_string(signing_key); FILE *f; size_t signed_len; char digest[DIGEST_LEN]; char signature[1024]; /* handles up to 8192-bit keys. */ int r; get_fingerprint(identity_key, fingerprint); get_digest(identity_key, id_digest); tor_localtime_r(&now, &tm); tm.tm_mon += months_lifetime; format_iso_time(published, now); format_iso_time(expires, mktime(&tm)); tor_snprintf(buf, sizeof(buf), "dir-key-certificate-version 3" "%s%s" "\nfingerprint %s\n" "dir-key-published %s\n" "dir-key-expires %s\n" "dir-identity-key\n%s" "dir-signing-key\n%s" "dir-key-crosscert\n" "-----BEGIN ID SIGNATURE-----\n", address?"\ndir-address ":"", address?address:"", fingerprint, published, expires, ident, signing ); tor_free(ident); tor_free(signing); /* Append a cross-certification */ r = RSA_private_encrypt(DIGEST_LEN, (unsigned char*)id_digest, (unsigned char*)signature, EVP_PKEY_get1_RSA(signing_key), RSA_PKCS1_PADDING); signed_len = strlen(buf); base64_encode(buf+signed_len, sizeof(buf)-signed_len, signature, r); strlcat(buf, "-----END ID SIGNATURE-----\n" "dir-key-certification\n", sizeof(buf)); signed_len = strlen(buf); SHA1((const unsigned char*)buf,signed_len,(unsigned char*)digest); r = RSA_private_encrypt(DIGEST_LEN, (unsigned char*)digest, (unsigned char*)signature, EVP_PKEY_get1_RSA(identity_key), RSA_PKCS1_PADDING); strlcat(buf, "-----BEGIN SIGNATURE-----\n", sizeof(buf)); signed_len = strlen(buf); base64_encode(buf+signed_len, sizeof(buf)-signed_len, signature, r); strlcat(buf, "-----END SIGNATURE-----\n", sizeof(buf)); if (!(f = fopen(certificate_file, "w"))) { log_err(LD_GENERAL, "Couldn't open %s for writing: %s", certificate_file, strerror(errno)); return 1; } fputs(buf, f); fclose(f); return 0; }
int ndn_keypair(int public_only, struct ndn_pkey *private_key, PyObject **py_private_key_ndn, PyObject **py_public_key_ndn) { struct ndn_pkey *public_key = NULL; struct ndn_pkey *private_key_copy = NULL; PyObject *py_private_key = NULL, *py_public_key = NULL; unsigned int err; int r; if (!public_only && py_private_key_ndn) { private_key_copy = (struct ndn_pkey *) EVP_PKEY_new(); JUMP_IF_NULL(private_key_copy, openssl_error); py_private_key = NDNObject_New(PKEY_PRIV, private_key_copy); JUMP_IF_NULL(py_private_key, error); RSA *private_key_rsa = EVP_PKEY_get1_RSA ((EVP_PKEY *)private_key); JUMP_IF_NULL(private_key_rsa, openssl_error); RSA* private_key_rsa_copy = RSAPrivateKey_dup (private_key_rsa); JUMP_IF_NULL(private_key_rsa_copy, openssl_error); r = EVP_PKEY_set1_RSA((EVP_PKEY *) private_key_copy, private_key_rsa_copy); RSA_free(private_key_rsa_copy); JUMP_IF_NULL(r, error); } if (py_public_key_ndn) { public_key = (struct ndn_pkey *) EVP_PKEY_new(); JUMP_IF_NULL(public_key, openssl_error); py_public_key = NDNObject_New(PKEY_PUB, public_key); JUMP_IF_NULL(py_public_key, error); RSA *private_key_rsa = EVP_PKEY_get1_RSA ((EVP_PKEY *)private_key); JUMP_IF_NULL(private_key_rsa, openssl_error); RSA* public_key_rsa = RSAPublicKey_dup (private_key_rsa); JUMP_IF_NULL(public_key_rsa, openssl_error); r = EVP_PKEY_set1_RSA((EVP_PKEY *) public_key, public_key_rsa); RSA_free(public_key_rsa); JUMP_IF_NULL(r, error); } if (py_private_key_ndn) { *py_private_key_ndn = public_only ? (Py_INCREF(Py_None), Py_None) : py_private_key; } if (py_public_key_ndn) *py_public_key_ndn = py_public_key; return 0; openssl_error: err = ERR_get_error(); PyErr_Format(g_PyExc_NDNKeyError, "Unable to generate keypair from the key:" " %s", ERR_reason_error_string(err)); error: if (!py_public_key && public_key) ndn_pubkey_free(public_key); Py_XDECREF(py_public_key); Py_XDECREF(py_private_key); return -1; }
/** * @retval 1 equal * @retval 0 not equal * @retval -1 error */ static int CompareCertToRSA(X509 *cert, RSA *rsa_key) { int ret; int retval = -1; /* ERROR */ EVP_PKEY *cert_pkey = X509_get_pubkey(cert); if (cert_pkey == NULL) { Log(LOG_LEVEL_ERR, "X509_get_pubkey: %s", TLSErrorString(ERR_get_error())); goto ret1; } if (EVP_PKEY_type(cert_pkey->type) != EVP_PKEY_RSA) { Log(LOG_LEVEL_ERR, "Received key of unknown type, only RSA currently supported!"); goto ret2; } RSA *cert_rsa_key = EVP_PKEY_get1_RSA(cert_pkey); if (cert_rsa_key == NULL) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_get1_RSA failed!"); goto ret2; } EVP_PKEY *rsa_pkey = EVP_PKEY_new(); if (rsa_pkey == NULL) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_new allocation failed!"); goto ret3; } ret = EVP_PKEY_set1_RSA(rsa_pkey, rsa_key); if (ret == 0) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_set1_RSA failed!"); goto ret4; } ret = EVP_PKEY_cmp(cert_pkey, rsa_pkey); if (ret == 1) { Log(LOG_LEVEL_DEBUG, "Public key to certificate compare equal"); retval = 1; /* EQUAL */ } else if (ret == 0 || ret == -1) { Log(LOG_LEVEL_DEBUG, "Public key to certificate compare different"); retval = 0; /* NOT EQUAL */ } else { Log(LOG_LEVEL_ERR, "OpenSSL EVP_PKEY_cmp: %d %s", ret, TLSErrorString(ERR_get_error())); } ret4: EVP_PKEY_free(rsa_pkey); ret3: RSA_free(cert_rsa_key); ret2: EVP_PKEY_free(cert_pkey); ret1: return retval; }
int sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) { #ifdef ENABLE_OPENSSL EVP_PKEY *pk = (EVP_PKEY *)evp_key; switch (pk->type) { case EVP_PKEY_RSA: { struct sc_pkcs15_pubkey_rsa *dst = &pkcs15_key->u.rsa; RSA *src = EVP_PKEY_get1_RSA(pk); pkcs15_key->algorithm = SC_ALGORITHM_RSA; if (!sc_pkcs15_convert_bignum(&dst->modulus, src->n) || !sc_pkcs15_convert_bignum(&dst->exponent, src->e)) return SC_ERROR_INVALID_DATA; RSA_free(src); break; } case EVP_PKEY_DSA: { struct sc_pkcs15_pubkey_dsa *dst = &pkcs15_key->u.dsa; DSA *src = EVP_PKEY_get1_DSA(pk); pkcs15_key->algorithm = SC_ALGORITHM_DSA; sc_pkcs15_convert_bignum(&dst->pub, src->pub_key); sc_pkcs15_convert_bignum(&dst->p, src->p); sc_pkcs15_convert_bignum(&dst->q, src->q); sc_pkcs15_convert_bignum(&dst->g, src->g); DSA_free(src); break; } #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) case NID_id_GostR3410_2001: { struct sc_pkcs15_pubkey_gostr3410 *dst = &pkcs15_key->u.gostr3410; EC_KEY *eckey = EVP_PKEY_get0(pk); const EC_POINT *point; BIGNUM *X, *Y; int r = 0; assert(eckey); point = EC_KEY_get0_public_key(eckey); if (!point) return SC_ERROR_INTERNAL; X = BN_new(); Y = BN_new(); if (X && Y && EC_KEY_get0_group(eckey)) r = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(eckey), point, X, Y, NULL); if (r == 1) { dst->xy.len = BN_num_bytes(X) + BN_num_bytes(Y); dst->xy.data = malloc(dst->xy.len); if (dst->xy.data) { BN_bn2bin(Y, dst->xy.data); BN_bn2bin(X, dst->xy.data + BN_num_bytes(Y)); r = sc_mem_reverse(dst->xy.data, dst->xy.len); if (!r) r = 1; pkcs15_key->algorithm = SC_ALGORITHM_GOSTR3410; } else r = -1; } BN_free(X); BN_free(Y); if (r != 1) return SC_ERROR_INTERNAL; break; } case EVP_PKEY_EC: { struct sc_pkcs15_pubkey_ec *dst = &pkcs15_key->u.ec; EC_KEY *src = NULL; const EC_GROUP *grp = NULL; unsigned char buf[255]; size_t buflen = 255; int nid; src = EVP_PKEY_get0(pk); assert(src); assert(EC_KEY_get0_public_key(src)); pkcs15_key->algorithm = SC_ALGORITHM_EC; grp = EC_KEY_get0_group(src); if(grp == 0) return SC_ERROR_INCOMPATIBLE_KEY; /* Decode EC_POINT from a octet string */ buflen = EC_POINT_point2oct(grp, (const EC_POINT *) EC_KEY_get0_public_key(src), POINT_CONVERSION_UNCOMPRESSED, buf, buflen, NULL); /* get curve name */ nid = EC_GROUP_get_curve_name(grp); if(nid != 0) { const char *name = OBJ_nid2sn(nid); if(sizeof(name) > 0) dst->params.named_curve = strdup(name); } /* copy the public key */ if (buflen > 0) { dst->ecpointQ.value = malloc(buflen); memcpy(dst->ecpointQ.value, buf, buflen); dst->ecpointQ.len = buflen; /* calculate the field length */ dst->params.field_length = (buflen - 1) / 2 * 8; } else return SC_ERROR_INCOMPATIBLE_KEY; break; } #endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) */ default: return SC_ERROR_NOT_SUPPORTED; } return SC_SUCCESS; #else return SC_ERROR_NOT_IMPLEMENTED; #endif }
static int sshkey_parse_private_pem(struct sshbuf *blob, int type, const char *passphrase, struct sshkey **keyp, char **commentp) { EVP_PKEY *pk = NULL; struct sshkey *prv = NULL; char *name = "<no key>"; BIO *bio = NULL; int r; *keyp = NULL; if (commentp != NULL) *commentp = NULL; if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX) return SSH_ERR_ALLOC_FAIL; if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) != (int)sshbuf_len(blob)) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase)) == NULL) { r = SSH_ERR_KEY_WRONG_PASSPHRASE; goto out; } if (pk->type == EVP_PKEY_RSA && (type == KEY_UNSPEC || type == KEY_RSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } prv->rsa = EVP_PKEY_get1_RSA(pk); prv->type = KEY_RSA; name = "rsa w/o comment"; #ifdef DEBUG_PK RSA_print_fp(stderr, prv->rsa, 8); #endif if (RSA_blinding_on(prv->rsa, NULL) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } } else if (pk->type == EVP_PKEY_DSA && (type == KEY_UNSPEC || type == KEY_DSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } prv->dsa = EVP_PKEY_get1_DSA(pk); prv->type = KEY_DSA; name = "dsa w/o comment"; #ifdef DEBUG_PK DSA_print_fp(stderr, prv->dsa, 8); #endif } else if (pk->type == EVP_PKEY_EC && (type == KEY_UNSPEC || type == KEY_ECDSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); prv->type = KEY_ECDSA; prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa); if (prv->ecdsa_nid == -1 || sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), EC_KEY_get0_public_key(prv->ecdsa)) != 0 || sshkey_ec_validate_private(prv->ecdsa) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } name = "ecdsa w/o comment"; #ifdef DEBUG_PK if (prv != NULL && prv->ecdsa != NULL) sshkey_dump_ec_key(prv->ecdsa); #endif } else { r = SSH_ERR_INVALID_FORMAT; goto out; } if (commentp != NULL && (*commentp = strdup(name)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } r = 0; *keyp = prv; prv = NULL; out: BIO_free(bio); if (pk != NULL) EVP_PKEY_free(pk); if (prv != NULL) sshkey_free(prv); return r; }
RTDECL(int) RTRSAVerify(void *pvBuf, unsigned int cbSize, const char* pManifestDigestIn, RTDIGESTTYPE digestType) { int rc = VINF_SUCCESS; unsigned char* pSignatureRSA = NULL; unsigned char* pManifestDigestOut = NULL; X509 *certificate = NULL; EVP_PKEY * evp_key = NULL; RSA * rsa_key = NULL; while(1) { unsigned int siglen = 0; rc = RTX509ConvertCertificateToBinary(pvBuf, &pSignatureRSA, &siglen); if (RT_FAILURE(rc)) { /*pSignatureRSA isn't allocated in this case, thus there is no need to free it*/ break; } unsigned int diglen = 0; rc = RTConvertDigestToBinary(pManifestDigestIn,&pManifestDigestOut, digestType, &diglen); if (RT_FAILURE(rc)) { /*pManifestDigestOut isn't allocated in this case, thus there is no need to free it*/ break; } rc = rtX509ReadCertificateFromPEM(pvBuf, cbSize, &certificate); if (RT_FAILURE(rc)) { /*memory for certificate isn't allocated in this case, thus there is no need to free it*/ break; } evp_key = X509_get_pubkey(certificate); if (evp_key == NULL) { rc = VERR_X509_EXTRACT_PUBKEY_FROM_CERT; break; } rsa_key = EVP_PKEY_get1_RSA(evp_key); if (rsa_key == NULL) { rc = VERR_X509_EXTRACT_RSA_FROM_PUBLIC_KEY; break; } rc = RSA_verify(NID_sha1, pManifestDigestOut, diglen, pSignatureRSA, siglen, rsa_key); if (rc != 1) { rc = VERR_X509_RSA_VERIFICATION_FUILURE; } break; }//end while(1) if(rsa_key) RSA_free(rsa_key); if(evp_key) EVP_PKEY_free(evp_key); if(certificate) X509_free(certificate); if (pManifestDigestOut) RTMemFree(pManifestDigestOut); if (pSignatureRSA) RTMemFree(pSignatureRSA); return rc; }
/* * Store private key */ static int pkcs11_store_key(PKCS11_TOKEN *token, EVP_PKEY *pk, unsigned int type, char *label, unsigned char *id, size_t id_len, PKCS11_KEY ** ret_key) { PKCS11_SLOT *slot = TOKEN2SLOT(token); PKCS11_CTX *ctx = TOKEN2CTX(token); PKCS11_SLOT_private *spriv = PRIVSLOT(slot); CK_OBJECT_HANDLE object; CK_ATTRIBUTE attrs[32]; unsigned int n = 0; int rv; const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_p, *rsa_q; /* First, make sure we have a session */ if (!spriv->haveSession && PKCS11_open_session(slot, 1)) return -1; /* Now build the key attrs */ pkcs11_addattr_int(attrs + n++, CKA_CLASS, type); if (label) pkcs11_addattr_s(attrs + n++, CKA_LABEL, label); if (id && id_len) pkcs11_addattr(attrs + n++, CKA_ID, id, id_len); pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE); if (type == CKO_PRIVATE_KEY) { pkcs11_addattr_bool(attrs + n++, CKA_PRIVATE, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_SENSITIVE, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_DECRYPT, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_SIGN, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_UNWRAP, TRUE); } else { /* CKO_PUBLIC_KEY */ pkcs11_addattr_bool(attrs + n++, CKA_ENCRYPT, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_VERIFY, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_WRAP, TRUE); } #if OPENSSL_VERSION_NUMBER >= 0x10100003L if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA) { RSA *rsa = EVP_PKEY_get1_RSA(pk); #else if (pk->type == EVP_PKEY_RSA) { RSA *rsa = pk->pkey.rsa; #endif pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA); #if OPENSSL_VERSION_NUMBER >= 0x10100005L RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); RSA_get0_factors(rsa, &rsa_p, &rsa_q); #else rsa_n=rsa->n; rsa_e=rsa->e; rsa_d=rsa->d; rsa_p=rsa->p; rsa_q=rsa->q; #endif pkcs11_addattr_bn(attrs + n++, CKA_MODULUS, rsa_n); pkcs11_addattr_bn(attrs + n++, CKA_PUBLIC_EXPONENT, rsa_e); if (type == CKO_PRIVATE_KEY) { pkcs11_addattr_bn(attrs + n++, CKA_PRIVATE_EXPONENT, rsa_d); pkcs11_addattr_bn(attrs + n++, CKA_PRIME_1, rsa_p); pkcs11_addattr_bn(attrs + n++, CKA_PRIME_2, rsa_q); } } else { pkcs11_zap_attrs(attrs, n); PKCS11err(type == CKO_PRIVATE_KEY ? PKCS11_F_PKCS11_STORE_PRIVATE_KEY : PKCS11_F_PKCS11_STORE_PUBLIC_KEY, PKCS11_NOT_SUPPORTED); return -1; } /* Now call the pkcs11 module to create the object */ rv = CRYPTOKI_call(ctx, C_CreateObject(spriv->session, attrs, n, &object)); /* Zap all memory allocated when building the template */ pkcs11_zap_attrs(attrs, n); CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_PRIVATE_KEY, rv); /* Gobble the key object */ return pkcs11_init_key(ctx, token, spriv->session, object, type, ret_key); } /* * Get the key type */ int pkcs11_get_key_type(PKCS11_KEY *key) { PKCS11_KEY_private *kpriv = PRIVKEY(key); return kpriv->ops->type; }
/* If no hash function was used, finish with RSA_public_decrypt(). * If a hash function was used, we can make a big shortcut by * finishing with EVP_VerifyFinal(). */ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, const unsigned char *pubkey_params, int pubkey_params_len, CK_MECHANISM_TYPE mech, sc_pkcs11_operation_t *md, unsigned char *data, int data_len, unsigned char *signat, int signat_len) { int res; CK_RV rv = CKR_GENERAL_ERROR; EVP_PKEY *pkey; if (mech == CKM_GOSTR3410) { #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) return gostr3410_verify_data(pubkey, pubkey_len, pubkey_params, pubkey_params_len, data, data_len, signat, signat_len); #else (void)pubkey_params, (void)pubkey_params_len; /* no warning */ return CKR_FUNCTION_NOT_SUPPORTED; #endif } pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &pubkey, pubkey_len); if (pkey == NULL) return CKR_GENERAL_ERROR; if (md != NULL) { EVP_MD_CTX *md_ctx = DIGEST_CTX(md); res = EVP_VerifyFinal(md_ctx, signat, signat_len, pkey); EVP_PKEY_free(pkey); if (res == 1) return CKR_OK; else if (res == 0) return CKR_SIGNATURE_INVALID; else { sc_debug(context, SC_LOG_DEBUG_NORMAL, "EVP_VerifyFinal() returned %d\n", res); return CKR_GENERAL_ERROR; } } else { RSA *rsa; unsigned char *rsa_out = NULL, pad; int rsa_outlen = 0; switch(mech) { case CKM_RSA_PKCS: pad = RSA_PKCS1_PADDING; break; case CKM_RSA_X_509: pad = RSA_NO_PADDING; break; default: EVP_PKEY_free(pkey); return CKR_ARGUMENTS_BAD; } rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); if (rsa == NULL) return CKR_DEVICE_MEMORY; rsa_out = malloc(RSA_size(rsa)); if (rsa_out == NULL) { RSA_free(rsa); return CKR_DEVICE_MEMORY; } rsa_outlen = RSA_public_decrypt(signat_len, signat, rsa_out, rsa, pad); RSA_free(rsa); if(rsa_outlen <= 0) { free(rsa_out); sc_debug(context, SC_LOG_DEBUG_NORMAL, "RSA_public_decrypt() returned %d\n", rsa_outlen); return CKR_GENERAL_ERROR; } if (rsa_outlen == data_len && memcmp(rsa_out, data, data_len) == 0) rv = CKR_OK; else rv = CKR_SIGNATURE_INVALID; free(rsa_out); } return rv; }
int rsautl_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; ENGINE *e = NULL; EVP_PKEY *pkey = NULL; RSA *rsa = NULL; X509 *x; char *infile = NULL, *outfile = NULL, *keyfile = NULL; char *passinarg = NULL, *passin = NULL, *prog; char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; unsigned char *rsa_in = NULL, *rsa_out = NULL, pad = RSA_PKCS1_PADDING; int rsa_inlen, keyformat = FORMAT_PEM, keysize, ret = 1; int rsa_outlen = 0, hexdump = 0, asn1parse = 0, need_priv = 0, rev = 0; OPTION_CHOICE o; prog = opt_init(argc, argv, rsautl_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(rsautl_options); ret = 0; goto end; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_ASN1PARSE: asn1parse = 1; break; case OPT_HEXDUMP: hexdump = 1; break; case OPT_RAW: pad = RSA_NO_PADDING; break; case OPT_OAEP: pad = RSA_PKCS1_OAEP_PADDING; break; case OPT_SSL: pad = RSA_SSLV23_PADDING; break; case OPT_PKCS: pad = RSA_PKCS1_PADDING; break; case OPT_X931: pad = RSA_X931_PADDING; break; case OPT_SIGN: rsa_mode = RSA_SIGN; need_priv = 1; break; case OPT_VERIFY: rsa_mode = RSA_VERIFY; break; case OPT_REV: rev = 1; break; case OPT_ENCRYPT: rsa_mode = RSA_ENCRYPT; break; case OPT_DECRYPT: rsa_mode = RSA_DECRYPT; need_priv = 1; break; case OPT_PUBIN: key_type = KEY_PUBKEY; break; case OPT_CERTIN: key_type = KEY_CERT; break; case OPT_INKEY: keyfile = opt_arg(); break; case OPT_PASSIN: passinarg = opt_arg(); break; } } argc = opt_num_rest(); argv = opt_rest(); if (need_priv && (key_type != KEY_PRIVKEY)) { BIO_printf(bio_err, "A private key is needed for this operation\n"); goto end; } if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (!app_load_modules(NULL)) goto end; /* FIXME: seed PRNG only if needed */ app_RAND_load_file(NULL, 0); switch (key_type) { case KEY_PRIVKEY: pkey = load_key(keyfile, keyformat, 0, passin, e, "Private Key"); break; case KEY_PUBKEY: pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "Public Key"); break; case KEY_CERT: x = load_cert(keyfile, keyformat, NULL, e, "Certificate"); if (x) { pkey = X509_get_pubkey(x); X509_free(x); } break; } if (!pkey) { return 1; } rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); if (!rsa) { BIO_printf(bio_err, "Error getting RSA key\n"); ERR_print_errors(bio_err); goto end; } in = bio_open_default(infile, 'r', FORMAT_BINARY); if (in == NULL) goto end; out = bio_open_default(outfile, 'w', FORMAT_BINARY); if (out == NULL) goto end; keysize = RSA_size(rsa); rsa_in = app_malloc(keysize * 2, "hold rsa key"); rsa_out = app_malloc(keysize, "output rsa key"); /* Read the input data */ rsa_inlen = BIO_read(in, rsa_in, keysize * 2); if (rsa_inlen <= 0) { BIO_printf(bio_err, "Error reading input Data\n"); goto end; } if (rev) { int i; unsigned char ctmp; for (i = 0; i < rsa_inlen / 2; i++) { ctmp = rsa_in[i]; rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; rsa_in[rsa_inlen - 1 - i] = ctmp; } } switch (rsa_mode) { case RSA_VERIFY: rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; case RSA_SIGN: rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; case RSA_ENCRYPT: rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; case RSA_DECRYPT: rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; } if (rsa_outlen <= 0) { BIO_printf(bio_err, "RSA operation error\n"); ERR_print_errors(bio_err); goto end; } ret = 0; if (asn1parse) { if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { ERR_print_errors(bio_err); } } else if (hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen); else BIO_write(out, rsa_out, rsa_outlen); end: RSA_free(rsa); BIO_free(in); BIO_free_all(out); OPENSSL_free(rsa_in); OPENSSL_free(rsa_out); OPENSSL_free(passin); return ret; }
/*============================================================================ * 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; }
int main(int argc, char **argv) { CK_ULONG nslots; CK_SLOT_ID *pslots = NULL; CK_FUNCTION_LIST *funcs = NULL; CK_UTF8CHAR_PTR opt_pin = NULL; CK_ULONG opt_pin_len = 0; CK_RV rc; CK_ULONG opt_slot = -1; CK_SESSION_HANDLE h_session; char *opt_module = NULL, *opt_dir = NULL; /* struct sockaddr_un sockaddr; */ int long_optind = 0; int fd, verbose = 0; key_id_t *rsa_keys, *ec_keys; CK_ULONG rsa_len = 0, ec_len = 0, i; init_crypto(); while (1) { char c = getopt_long(argc, argv, "d:hp:s:m:v", options, &long_optind); if (c == -1) break; switch (c) { case 'd': opt_dir = optarg; break; case 'p': opt_pin = (CK_UTF8CHAR_PTR) strdup(optarg); if(opt_pin) { opt_pin_len = strlen(optarg); } break; case 's': opt_slot = (CK_SLOT_ID) atoi(optarg); break; case 'm': opt_module = optarg; break; case 'v': verbose = 1; break; case 'h': default: print_usage_and_die(app_name, options, option_help); } } rc = pkcs11_load_init(opt_module, opt_dir, stderr, &funcs); if (rc != CKR_OK) { return rc; } rc = pkcs11_get_slots(funcs, stderr, &pslots, &nslots); if (rc != CKR_OK) { return rc; } if(opt_slot == -1) { if(nslots < 1) { /* No slots */ return -1; } else { opt_slot = pslots[0]; } } else { /* Check selected slot is in pslots */ } fprintf(stderr, "Slot: %ld\n", opt_slot); rc = pkcs11_login_session(funcs, stderr, opt_slot, &h_session, CK_TRUE, CKU_USER, opt_pin, opt_pin_len); if (rc != CKR_OK) { show_error(stderr, "Login", rc); return rc; } load_keys(funcs, h_session, CKK_RSA, &rsa_keys, &rsa_len); load_keys(funcs, h_session, CKK_EC, &ec_keys, &ec_len); /* fd = nw_unix_server("pkcs11d.sock", &sockaddr, 0, 0, 0, 64); */ /* close(fd); */ fd = nw_tcp_server(1234, 0, 64); do { struct sockaddr address; socklen_t a_len = sizeof(address); int s = accept(fd, &address, &a_len); BIO *b = BIO_new_socket(s, BIO_NOCLOSE); BIO *buf = BIO_new(BIO_f_buffer()); b = BIO_push(buf, b); char buffer[4096], sig[4096], keyid[KEY_ID_SIZE + 1]; int l, slen = 0, plen = 0; CK_KEY_TYPE type; CK_ATTRIBUTE_TYPE operation; EVP_PKEY *pkey = NULL; l = BIO_gets(b, buffer, sizeof(buffer)); if(l <= 0) { fprintf(stderr, "Error reading query line\n"); goto end; } if(strncmp(buffer, "POST /sign/rsa/", 15) == 0) { memcpy(keyid, buffer + 15, KEY_ID_SIZE - 1); type = CKK_RSA; operation = CKA_SIGN; } else if(strncmp(buffer, "POST /decrypt/rsa/", 18) == 0) { memcpy(keyid, buffer + 18, KEY_ID_SIZE - 1); type = CKK_RSA; operation = CKA_DECRYPT; } else if(strncmp(buffer, "POST /sign/ec/", 14) == 0) { memcpy(keyid, buffer + 14, KEY_ID_SIZE - 1); type = CKK_EC; operation = CKA_SIGN; } else { goto end; } keyid[KEY_ID_SIZE] = '\0'; l = BIO_gets(b, buffer, sizeof(buffer)); if((l <= 0) || strncmp(buffer, "Content-Length: ", 16) != 0) { fprintf(stderr, "Invalid content length line = %s\n", buffer); goto end; } plen = atoi(buffer + 16); l = BIO_gets(b, buffer, sizeof(buffer)); l = BIO_read(b, buffer, plen); if(l < plen) { fprintf(stderr, "Error reading payload\n"); goto end; } if(type == CKK_RSA) { for(i = 0; (i < rsa_len) && (pkey == NULL); i++) { if(strncmp(rsa_keys[i].id, keyid, KEY_ID_SIZE - 1) == 0) { pkey = rsa_keys[i].key; } } } else if(type == CKK_EC) { for(i = 0; (i < ec_len) && (pkey == NULL); i++) { if(strncmp(ec_keys[i].id, keyid, KEY_ID_SIZE - 1) == 0) { pkey = ec_keys[i].key; } } } if(pkey == NULL) { fprintf(stderr, "Key not found\n"); goto end; } else if(verbose) { fprintf(stderr, "Key '%s'found\n", keyid); } if(type == CKK_RSA && operation == CKA_SIGN) { if(verbose) { fprintf(stderr, "RSA signature operation requested\n"); } l = RSA_private_encrypt(plen, (unsigned char *)buffer, (unsigned char *)sig, EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING); } else if(type == CKK_RSA && operation == CKA_DECRYPT) { if(verbose) { fprintf(stderr, "RSA decryption operation requested\n"); } l = RSA_private_decrypt(plen, (unsigned char *)buffer, (unsigned char *)sig, EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING); } else if (type == CKK_EC && operation == CKA_SIGN) { unsigned char *ptr = (unsigned char *)sig; ECDSA_SIG *s = ECDSA_do_sign((unsigned char *)buffer, plen, EVP_PKEY_get1_EC_KEY(pkey)); l = i2d_ECDSA_SIG(s, &ptr); ECDSA_SIG_free(s); } else { if(verbose) { fprintf(stderr, "Invalid operation requested\n"); } goto end; } slen = l; if(l <= 0) { if(verbose) { fprintf(stderr, "Error unsuccessful\n"); } goto end; } else if(verbose) { fprintf(stderr, "Operation successful\n"); } BIO_printf(b, "200 Ok\r\n"); BIO_printf(b, "Content-Length: %d\r\n\r\n", slen); l = BIO_write(b, sig, slen); BIO_flush(b); i= 0; /* for(i = 0; i < rsa_len; i++) { BIO_write(b, rsa_keys[i].id, KEY_ID_SIZE); BIO_write(b, "\n", 1); PEM_write_bio_RSAPrivateKey(b, EVP_PKEY_get1_RSA(rsa_keys[i].key), NULL, NULL, 0, NULL, NULL); } for(i = 0; i < ec_len; i++) { BIO_write(b, ec_keys[i].id, KEY_ID_SIZE); BIO_write(b, "\n", 1); PEM_write_bio_ECPrivateKey(b, EVP_PKEY_get1_EC_KEY(ec_keys[i].key), NULL, NULL, 0, NULL, NULL); } */ end: close(s); BIO_free(b); } while(1); close(fd); if(opt_pin) { funcs->C_CloseAllSessions(opt_slot); free(opt_pin); } rc = funcs->C_Finalize(NULL); if (rc != CKR_OK) { show_error(stderr, "C_Finalize", rc); return rc; } return rc; }
int rsa_main(int argc, char **argv) { int ret = 1; RSA *rsa = NULL; int i; BIO *out = NULL; char *passin = NULL, *passout = NULL; if (single_execution) { if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { perror("pledge"); exit(1); } } memset(&rsa_config, 0, sizeof(rsa_config)); rsa_config.pvk_encr = 2; rsa_config.informat = FORMAT_PEM; rsa_config.outformat = FORMAT_PEM; if (options_parse(argc, argv, rsa_options, NULL, NULL) != 0) { rsa_usage(); goto end; } if (!app_passwd(bio_err, rsa_config.passargin, rsa_config.passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if (rsa_config.check && rsa_config.pubin) { BIO_printf(bio_err, "Only private keys can be checked\n"); goto end; } out = BIO_new(BIO_s_file()); { EVP_PKEY *pkey; if (rsa_config.pubin) { int tmpformat = -1; if (rsa_config.pubin == 2) { if (rsa_config.informat == FORMAT_PEM) tmpformat = FORMAT_PEMRSA; else if (rsa_config.informat == FORMAT_ASN1) tmpformat = FORMAT_ASN1RSA; } else if (rsa_config.informat == FORMAT_NETSCAPE && rsa_config.sgckey) tmpformat = FORMAT_IISSGC; else tmpformat = rsa_config.informat; pkey = load_pubkey(bio_err, rsa_config.infile, tmpformat, 1, passin, "Public Key"); } else pkey = load_key(bio_err, rsa_config.infile, (rsa_config.informat == FORMAT_NETSCAPE && rsa_config.sgckey ? FORMAT_IISSGC : rsa_config.informat), 1, passin, "Private Key"); if (pkey != NULL) rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); } if (rsa == NULL) { ERR_print_errors(bio_err); goto end; } if (rsa_config.outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, rsa_config.outfile) <= 0) { perror(rsa_config.outfile); goto end; } } if (rsa_config.text) if (!RSA_print(out, rsa, 0)) { perror(rsa_config.outfile); ERR_print_errors(bio_err); goto end; } if (rsa_config.modulus) { BIO_printf(out, "Modulus="); BN_print(out, rsa->n); BIO_printf(out, "\n"); } if (rsa_config.check) { int r = RSA_check_key(rsa); if (r == 1) BIO_printf(out, "RSA key ok\n"); else if (r == 0) { unsigned long err; while ((err = ERR_peek_error()) != 0 && ERR_GET_LIB(err) == ERR_LIB_RSA && ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY && ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) { BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err)); ERR_get_error(); /* remove e from error * stack */ } } if (r == -1 || ERR_peek_error() != 0) { /* should happen only if * r == -1 */ ERR_print_errors(bio_err); goto end; } } if (rsa_config.noout) { ret = 0; goto end; } BIO_printf(bio_err, "writing RSA key\n"); if (rsa_config.outformat == FORMAT_ASN1) { if (rsa_config.pubout || rsa_config.pubin) { if (rsa_config.pubout == 2) i = i2d_RSAPublicKey_bio(out, rsa); else i = i2d_RSA_PUBKEY_bio(out, rsa); } else i = i2d_RSAPrivateKey_bio(out, rsa); } #ifndef OPENSSL_NO_RC4 else if (rsa_config.outformat == FORMAT_NETSCAPE) { unsigned char *p, *pp; int size; i = 1; size = i2d_RSA_NET(rsa, NULL, NULL, rsa_config.sgckey); if ((p = malloc(size)) == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); goto end; } pp = p; i2d_RSA_NET(rsa, &p, NULL, rsa_config.sgckey); BIO_write(out, (char *) pp, size); free(pp); } #endif else if (rsa_config.outformat == FORMAT_PEM) { if (rsa_config.pubout || rsa_config.pubin) { if (rsa_config.pubout == 2) i = PEM_write_bio_RSAPublicKey(out, rsa); else i = PEM_write_bio_RSA_PUBKEY(out, rsa); } else i = PEM_write_bio_RSAPrivateKey(out, rsa, rsa_config.enc, NULL, 0, NULL, passout); #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) } else if (rsa_config.outformat == FORMAT_MSBLOB || rsa_config.outformat == FORMAT_PVK) { EVP_PKEY *pk; pk = EVP_PKEY_new(); EVP_PKEY_set1_RSA(pk, rsa); if (rsa_config.outformat == FORMAT_PVK) i = i2b_PVK_bio(out, pk, rsa_config.pvk_encr, 0, passout); else if (rsa_config.pubin || rsa_config.pubout) i = i2b_PublicKey_bio(out, pk); else i = i2b_PrivateKey_bio(out, pk); EVP_PKEY_free(pk); #endif } else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (i <= 0) { BIO_printf(bio_err, "unable to write key\n"); ERR_print_errors(bio_err); } else ret = 0; end: BIO_free_all(out); RSA_free(rsa); free(passin); free(passout); return (ret); }
int load_keys(CK_FUNCTION_LIST *funcs, CK_SESSION_HANDLE h_session, CK_KEY_TYPE type, key_id_t **out, CK_ULONG_PTR len) { CK_RV rc; CK_ULONG l, i, j = 0; CK_OBJECT_HANDLE handles[1024]; key_id_t *keys = NULL; CK_OBJECT_CLASS pkey = CKO_PRIVATE_KEY; const EVP_MD *hash = EVP_sha256(); unsigned char md[EVP_MAX_MD_SIZE]; char key_id[KEY_ID_SIZE + 1]; CK_ATTRIBUTE search[2] = { { CKA_CLASS, &pkey, sizeof(pkey)}, { CKA_KEY_TYPE, &type, sizeof(type) }, }; rc = funcs->C_FindObjectsInit(h_session, search, 2); if (rc != CKR_OK) { show_error(stderr, "C_FindObjectsInit", rc); return 1; } rc = funcs->C_FindObjects(h_session, handles, 1024, &l); if (rc != CKR_OK) { show_error(stderr, "C_FindObjects", rc); return 1; } rc = funcs->C_FindObjectsFinal(h_session); if (rc != CKR_OK) { show_error(stderr, "C_FindObjectsFinal", rc); } keys = (key_id_t*)calloc(l, sizeof(key_id_t)); if(keys == NULL) { return 1; } fprintf(stderr, "Found: %ld objects\n", l); BIO *bio = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); for(i = 0; i < l; i++) { // print_object_info(funcs, stderr, i, h_session, handles[i]); keys[j].key = load_pkcs11_key(funcs, h_session, handles[i]); if(keys[j].key) { unsigned int k, l, n; BIO *s = BIO_new(BIO_s_null()); BIO *h = BIO_new(BIO_f_md()); BIO_set_md(h, hash); s = BIO_push(h, s); if(type == CKK_RSA) { i2d_RSAPublicKey_bio(s, EVP_PKEY_get1_RSA(keys[j].key)); PEM_write_bio_RSAPrivateKey(bio, EVP_PKEY_get1_RSA(keys[j].key), NULL, NULL, 0, NULL, NULL); } if(type == CKK_EC) { i2d_EC_PUBKEY_bio(s, EVP_PKEY_get1_EC_KEY(keys[j].key)); PEM_write_bio_ECPrivateKey(bio, EVP_PKEY_get1_EC_KEY(keys[j].key), NULL, NULL, 0, NULL, NULL); } n = BIO_gets(h, (char*)md, EVP_MAX_MD_SIZE); for(k = 0, l = 0; k < n; k++) { l += sprintf(key_id + l, "%02X", md[k]); } memcpy(keys[j].id, key_id, KEY_ID_SIZE); BIO_free_all(s); j += 1; } } if (bio) { BIO_free_all(bio); } if(out) { *out = keys; } else { for(i = 0; i < j; i++) { unload_pkcs11_key(keys[i].key); } } if(len) { *len = j; } return 0; }