security: Fix up use of OpenSSL

The switch to Go 1.6 means that there is no advantage to using OpenSSL's
crypto library (libcrypto) for ECDSA signing and verification on amd64.
However, on other architectures (such as ARM-based RaspberryPis and
Androids or Intel Edisons (386)) using libcrypto may still yield a
performance benefit over the implementation in the standard Go library
(which lacks optimized assembly for these architectures).

This change fixes up use of OpenSSL's libcrypto in this post 1.6 world.

(1) Simplified build tags: By default use the Go standard library.
    When the 'openssl' tag is specified, use that.

(2) Use cgo in a manner compatible with the stricter rules on
    pointer passing introduced in Go 1.6 (see
    https://golang.org/doc/go1.6#cgo).

    Specifically d2i_EC_PUBKEY and d2i_ECPrivateKey take
    an argument of type (char**), causing Go 1.6 to complain
    with a panic:
    "panic: runtime error: cgo argument has Go pointer to Go pointer"
    if that argument was backed by memory allocated by the Go runtime.

    However, the only reason the d2i_* functions take a
    pointer-to-a-pointer is to increment the input to
    the address following the parsed data (see
    https://www.openssl.org/docs/manmaster/crypto/d2i_X509.html),
    not to allocate memory and assign to that pointer.

    Thus, in this change, the wrapper openssl_d2i_* functions in
    openssl.c have been modified to trick the Go runtime into avoiding
    that check. This will cause subtle bugs if I misunderstood the
    contract the d2i_* functions have.

Change-Id: I62a3ebecee7c2afdc3f70f961f26a5db488cff6d
4 files changed