int aws_cryptosdk_sig_sign_start_keygen()

in source/cipher_openssl.c [447:523]


int aws_cryptosdk_sig_sign_start_keygen(
    struct aws_cryptosdk_sig_ctx **pctx,
    struct aws_allocator *alloc,
    struct aws_string **pub_key,
    const struct aws_cryptosdk_alg_properties *props) {
    AWS_PRECONDITION(AWS_OBJECT_PTR_IS_WRITABLE(pctx));
    AWS_PRECONDITION(AWS_OBJECT_PTR_IS_READABLE(alloc));
    AWS_PRECONDITION(AWS_OBJECT_PTR_IS_READABLE(props));
    EC_GROUP *group = NULL;
    EC_KEY *keypair = NULL;

    *pctx = NULL;
    if (pub_key) {
        *pub_key = NULL;
    }

    if (!props->impl->curve_name) {
        AWS_POSTCONDITION(!*pctx);
        AWS_POSTCONDITION(!pub_key || !*pub_key);
        return AWS_OP_SUCCESS;
    }

    group = group_for_props(props);
    if (!group) {
        goto err;
    }

    if (!(keypair = EC_KEY_new())) {
        goto err;
    }

    if (!EC_KEY_set_group(keypair, group)) {
        goto err;
    }

    if (!EC_KEY_generate_key(keypair)) {
        goto err;
    }

    if (pub_key && serialize_pubkey(alloc, keypair, pub_key)) {
        goto rethrow;
    }

    // If pub_key is NULL the conversion form is never set, and so it differs between the EC_KEY and EC_GROUP objects.
    // If this is not a problem this line can be removed, but ec_key_is_valid needs to be changed in the CBMC model.
    EC_KEY_set_conv_form(keypair, POINT_CONVERSION_COMPRESSED);

    *pctx = sign_start(alloc, keypair, props);
    if (!*pctx) {
        goto rethrow;
    }

    EC_KEY_free(keypair);
    EC_GROUP_free(group);

    AWS_POSTCONDITION(aws_cryptosdk_sig_ctx_is_valid(*pctx) && (*pctx)->is_sign);
    AWS_POSTCONDITION(!pub_key || aws_string_is_valid(*pub_key));
    return AWS_OP_SUCCESS;

err:
    aws_raise_error(AWS_CRYPTOSDK_ERR_CRYPTO_UNKNOWN);
rethrow:
    aws_cryptosdk_sig_abort(*pctx);
    *pctx = NULL;

    if (pub_key) {
        aws_string_destroy(*pub_key);
        *pub_key = NULL;
    }

    EC_KEY_free(keypair);
    EC_GROUP_free(group);

    AWS_POSTCONDITION(!*pctx);
    AWS_POSTCONDITION(!pub_key || !*pub_key);
    return AWS_OP_ERR;
}