Example #1
0
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 );
}
Example #2
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;
}