int write_certificate( x509write_cert *crt, char *output_file, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; FILE *f; unsigned char output_buf[4096]; size_t len = 0; memset( output_buf, 0, 4096 ); if( ( ret = x509write_crt_pem( crt, output_buf, 4096, f_rng, p_rng ) ) < 0 ) return( ret ); len = strlen( (char *) output_buf ); if( ( f = fopen( output_file, "w" ) ) == NULL ) return( -1 ); if( fwrite( output_buf, 1, len, f ) != len ) return( -1 ); fclose(f); return( 0 ); }
result_t X509Req::sign(const char *issuer, PKey_base *key, v8::Local<v8::Object> opts, obj_ptr<X509Cert_base> &retVal, exlib::AsyncEvent *ac) { result_t hr; bool priv; hr = key->isPrivate(priv); if (hr < 0) return hr; if (!priv) return CHECK_ERROR(CALL_E_INVALIDARG); int ret; std::string subject; pk_context *pk; int32_t hash; std::string buf; obj_ptr<X509Cert> cert; if (!ac) { mpi serial; v8::Local<v8::Value> v; x509write_crt_init(&m_crt); hr = GetConfigValue(opts, "hash", hash); if (hr == CALL_E_PARAMNOTOPTIONAL) hash = m_csr.sig_md; else if (hr < 0) goto exit; if (hash < POLARSSL_MD_MD2 || hash > POLARSSL_MD_RIPEMD160) { hr = CALL_E_INVALIDARG; goto exit; } x509write_crt_set_md_alg(&m_crt, POLARSSL_MD_SHA1); v = opts->Get(v8::String::NewFromUtf8(isolate, "serial", v8::String::kNormalString, 6)); if (!IsEmpty(v)) { v8::String::Utf8Value str(v); if (!*str) { hr = CHECK_ERROR(_ssl::setError(POLARSSL_ERR_MPI_BAD_INPUT_DATA)); goto exit; } mpi_init(&serial); ret = mpi_read_string(&serial, 10, *str); if (ret != 0) { mpi_free(&serial); hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } } else { mpi_init(&serial); mpi_lset(&serial, 1); } ret = x509write_crt_set_serial(&m_crt, &serial); if (ret != 0) { mpi_free(&serial); hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } mpi_free(&serial); date_t d1, d2; std::string s1, s2; hr = GetConfigValue(opts, "notBefore", d1); if (hr == CALL_E_PARAMNOTOPTIONAL) d1.now(); else if (hr < 0) goto exit; d1.toX509String(s1); hr = GetConfigValue(opts, "notAfter", d2); if (hr == CALL_E_PARAMNOTOPTIONAL) { d2 = d1; d2.add(1, date_t::_YEAR); } else if (hr < 0) goto exit; d2.toX509String(s2); ret = x509write_crt_set_validity(&m_crt, s1.c_str(), s2.c_str()); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } bool is_ca = false; hr = GetConfigValue(opts, "ca", is_ca); if (hr < 0 && hr != CALL_E_PARAMNOTOPTIONAL) goto exit; int32_t pathlen = -1; hr = GetConfigValue(opts, "pathlen", pathlen); if (hr < 0 && hr != CALL_E_PARAMNOTOPTIONAL) goto exit; if (pathlen < -1 || pathlen > 127) { hr = CALL_E_INVALIDARG; goto exit; } ret = x509write_crt_set_basic_constraints(&m_crt, is_ca ? 1 : 0, pathlen); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } int key_usage = parseString(opts->Get(v8::String::NewFromUtf8(isolate, "usage", v8::String::kNormalString, 5)), X509Cert::g_usages); if (key_usage < 0) { hr = key_usage; goto exit; } else if (key_usage) { ret = x509write_crt_set_key_usage(&m_crt, key_usage); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } } int cert_type = parseString(opts->Get(v8::String::NewFromUtf8(isolate, "type", v8::String::kNormalString, 4)), X509Cert::g_types); if (cert_type < 0) { hr = cert_type; goto exit; } else if (cert_type) { ret = x509write_crt_set_ns_cert_type(&m_crt, cert_type); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } } return CHECK_ERROR(CALL_E_NOSYNC); } pk = &((PKey *)key)->m_key; x509write_crt_set_subject_key(&m_crt, &m_csr.pk); x509write_crt_set_issuer_key(&m_crt, pk); hr = X509Req::get_subject(subject); if (hr < 0) goto exit; ret = x509write_crt_set_subject_name(&m_crt, subject.c_str()); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } ret = x509write_crt_set_issuer_name(&m_crt, issuer); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } ret = x509write_crt_set_subject_key_identifier(&m_crt); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } ret = x509write_crt_set_authority_key_identifier(&m_crt); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } buf.resize(pk_get_size(pk) * 8 + 128); ret = x509write_crt_pem(&m_crt, (unsigned char *)&buf[0], buf.length(), ctr_drbg_random, &g_ssl.ctr_drbg); if (ret < 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } cert = new X509Cert(); hr = cert->load(buf.c_str()); if (hr < 0) goto exit; retVal = cert; exit: x509write_crt_free(&m_crt); return hr; }