result_t PKey::exportPem(std::string &retVal) { result_t hr; bool priv; hr = isPrivate(priv); if (hr < 0) return hr; int32_t ret; std::string buf; buf.resize(mbedtls_pk_get_len(&m_key) * 8 + 128); if (priv) ret = mbedtls_pk_write_key_pem(&m_key, (unsigned char *)&buf[0], buf.length()); else ret = mbedtls_pk_write_pubkey_pem(&m_key, (unsigned char *)&buf[0], buf.length()); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); buf.resize(qstrlen(buf.c_str())); retVal = buf; return 0; }
static int write_private_key( mbedtls_pk_context *key, const char *output_file ) { int ret; FILE *f; unsigned char output_buf[16000]; unsigned char *c = output_buf; size_t len = 0; memset(output_buf, 0, 16000); #if defined(MBEDTLS_PEM_WRITE_C) if( opt.output_format == OUTPUT_FORMAT_PEM ) { if( ( ret = mbedtls_pk_write_key_pem( key, output_buf, 16000 ) ) != 0 ) return( ret ); len = strlen( (char *) output_buf ); } else #endif { if( ( ret = mbedtls_pk_write_key_der( key, output_buf, 16000 ) ) < 0 ) return( ret ); len = ret; c = output_buf + sizeof(output_buf) - len - 1; } if( ( f = fopen( output_file, "w" ) ) == NULL ) return( -1 ); if( fwrite( c, 1, len, f ) != len ) { fclose( f ); return( -1 ); } fclose( f ); return( 0 ); }
/* * CSR is output formatted as b64url(DER) * Private key is output as a PEM in memory */ LWS_VISIBLE LWS_EXTERN int lws_tls_acme_sni_csr_create(struct lws_context *context, const char *elements[], uint8_t *dcsr, size_t csr_len, char **privkey_pem, size_t *privkey_len) { mbedtls_x509write_csr csr; char subject[200]; mbedtls_pk_context mpk; int buf_size = 4096, n; uint8_t *buf = malloc(buf_size); /* malloc because given to user code */ if (!buf) return -1; mbedtls_x509write_csr_init(&csr); mbedtls_pk_init(&mpk); if (mbedtls_pk_setup(&mpk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA))) { lwsl_notice("%s: pk_setup failed\n", __func__); goto fail; } n = mbedtls_rsa_gen_key(mbedtls_pk_rsa(mpk), _rngf, context, lws_plat_recommended_rsa_bits(), 65537); if (n) { lwsl_notice("%s: failed to generate keys\n", __func__); goto fail1; } /* subject must be formatted like "C=TW,O=warmcat,CN=myserver" */ lws_snprintf(subject, sizeof(subject) - 1, "C=%s,ST=%s,L=%s,O=%s,CN=%s", elements[LWS_TLS_REQ_ELEMENT_COUNTRY], elements[LWS_TLS_REQ_ELEMENT_STATE], elements[LWS_TLS_REQ_ELEMENT_LOCALITY], elements[LWS_TLS_REQ_ELEMENT_ORGANIZATION], elements[LWS_TLS_REQ_ELEMENT_COMMON_NAME]); if (mbedtls_x509write_csr_set_subject_name(&csr, subject)) goto fail1; mbedtls_x509write_csr_set_key(&csr, &mpk); mbedtls_x509write_csr_set_md_alg(&csr, MBEDTLS_MD_SHA256); /* * data is written at the end of the buffer! Use the * return value to determine where you should start * using the buffer */ n = mbedtls_x509write_csr_der(&csr, buf, buf_size, _rngf, context); if (n < 0) { lwsl_notice("%s: write csr der failed\n", __func__); goto fail1; } /* we have it in DER, we need it in b64URL */ n = lws_jws_base64_enc((char *)(buf + buf_size) - n, n, (char *)dcsr, csr_len); if (n < 0) goto fail1; /* * okay, the CSR is done, last we need the private key in PEM * re-use the DER CSR buf as the result buffer since we cn do it in * one step */ if (mbedtls_pk_write_key_pem(&mpk, buf, buf_size)) { lwsl_notice("write key pem failed\n"); goto fail1; } *privkey_pem = (char *)buf; *privkey_len = strlen((const char *)buf); mbedtls_pk_free(&mpk); mbedtls_x509write_csr_free(&csr); return n; fail1: mbedtls_pk_free(&mpk); fail: mbedtls_x509write_csr_free(&csr); free(buf); return -1; }