=pod

=encoding UTF-8

=head1 NAME

proxy-certificates - Proxy certificates in OpenSSL

=head1 DESCRIPTION

Proxy certificates are defined in RFC 3820.  They are used to
extend rights to some other entity (a computer process, typically, or
sometimes to the user itself).  This allows the entity to perform
operations on behalf of the owner of the EE (End Entity) certificate.

The requirements for a valid proxy certificate are:

=over 4

=item *

They are issued by an End Entity, either a normal EE certificate, or
another proxy certificate.

=item *

They must not have the B<subjectAltName> or B<issuerAltName>
extensions.

=item *

They must have the B<proxyCertInfo> extension.

=item *

They must have the subject of their issuer, with one B<commonName>
added.

=back

=head2 Enabling proxy certificate verification

OpenSSL expects applications that want to use proxy certificates to be
specially aware of them, and make that explicit.  This is done by
setting an X509 verification flag:

    X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);

or

    X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_ALLOW_PROXY_CERTS);

See L</NOTES> for a discussion on this requirement.

=head2 Creating proxy certificates

Creating proxy certificates can be done using the L<openssl-x509(1)>
command, with some extra extensions:

    [ proxy ]
    # A proxy certificate MUST NEVER be a CA certificate.
    basicConstraints = CA:FALSE
    # Usual authority key ID
    authorityKeyIdentifier = keyid,issuer:always
    # The extension which marks this certificate as a proxy
    proxyCertInfo = critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB

It's also possible to specify the proxy extension in a separate section:

    proxyCertInfo = critical,@proxy_ext

    [ proxy_ext ]
    language = id-ppl-anyLanguage
    pathlen = 0
    policy = text:BC

The policy value has a specific syntax, I<syntag>:I<string>, where the
I<syntag> determines what will be done with the string.  The following
I<syntag>s are recognised:

=over 4

=item B<text>

indicates that the string is a byte sequence, without any encoding:

    policy=text:räksmörgås

=item B<hex>

indicates the string is encoded hexadecimal encoded binary data, with
colons between each byte (every second hex digit):

    policy=hex:72:E4:6B:73:6D:F6:72:67:E5:73

=item B<file>

indicates that the text of the policy should be taken from a file.
The string is then a filename.  This is useful for policies that are
more than a few lines, such as XML or other markup.

=back

Note that the proxy policy value is what determines the rights granted
to the process during the proxy certificate, and it is up to the
application to interpret and combine these policies.>

With a proxy extension, creating a proxy certificate is a matter of
two commands:

    openssl req -new -config proxy.cnf \
        -out proxy.req -keyout proxy.key \
        -subj "/DC=org/DC=openssl/DC=users/CN=proxy"

    openssl x509 -req -CAcreateserial -in proxy.req -out proxy.crt \
        -CA user.crt -CAkey user.key -days 7 \
        -extfile proxy.cnf -extensions proxy

You can also create a proxy certificate using another proxy
certificate as issuer. Note that this example uses a different
configuration section for the proxy extensions:

    openssl req -new -config proxy.cnf \
        -out proxy2.req -keyout proxy2.key \
        -subj "/DC=org/DC=openssl/DC=users/CN=proxy/CN=proxy 2"

    openssl x509 -req -CAcreateserial -in proxy2.req -out proxy2.crt \
        -CA proxy.crt -CAkey proxy.key -days 7 \
        -extfile proxy.cnf -extensions proxy_2

=head2 Using proxy certs in applications

To interpret proxy policies, the application would normally start with
some default rights (perhaps none at all), then compute the resulting
rights by checking the rights against the chain of proxy certificates,
user certificate and CA certificates.

The complicated part is figuring out how to pass data between your
application and the certificate validation procedure.

The following ingredients are needed for such processing:

=over 4

=item *

a callback function that will be called for every certificate being
validated.  The callback is called several times for each certificate,
so you must be careful to do the proxy policy interpretation at the
right time.  You also need to fill in the defaults when the EE
certificate is checked.

=item *

a data structure that is shared between your application code and the
callback.

=item *

a wrapper function that sets it all up.

=item *

an ex_data index function that creates an index into the generic
ex_data store that is attached to an X509 validation context.

=back

The following skeleton code can be used as a starting point:

    #include <string.h>
    #include <netdb.h>
    #include <openssl/x509.h>
    #include <openssl/x509v3.h>

    #define total_rights 25

    /*
     * In this example, I will use a view of granted rights as a bit
     * array, one bit for each possible right.
     */
    typedef struct your_rights {
        unsigned char rights[(total_rights + 7) / 8];
    } YOUR_RIGHTS;

    /*
     * The following procedure will create an index for the ex_data
     * store in the X509 validation context the first time it's
     * called.  Subsequent calls will return the same index.
     */
    static int get_proxy_auth_ex_data_idx(X509_STORE_CTX *ctx)
    {
        static volatile int idx = -1;

        if (idx < 0) {
            X509_STORE_lock(X509_STORE_CTX_get0_store(ctx));
            if (idx < 0) {
                idx = X509_STORE_CTX_get_ex_new_index(0,
                                                      "for verify callback",
                                                      NULL,NULL,NULL);
            }
            X509_STORE_unlock(X509_STORE_CTX_get0_store(ctx));
        }
        return idx;
    }

    /* Callback to be given to the X509 validation procedure.  */
    static int verify_callback(int ok, X509_STORE_CTX *ctx)
    {
        if (ok == 1) {
            /*
             * It's REALLY important you keep the proxy policy check
             * within this section.  It's important to know that when
             * ok is 1, the certificates are checked from top to
             * bottom.  You get the CA root first, followed by the
             * possible chain of intermediate CAs, followed by the EE
             * certificate, followed by the possible proxy
             * certificates.
             */
            X509 *xs = X509_STORE_CTX_get_current_cert(ctx);

            if (X509_get_extension_flags(xs) & EXFLAG_PROXY) {
                YOUR_RIGHTS *rights =
                    (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
                        get_proxy_auth_ex_data_idx(ctx));
                PROXY_CERT_INFO_EXTENSION *pci =
                    X509_get_ext_d2i(xs, NID_proxyCertInfo, NULL, NULL);

                switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) {
                case NID_Independent:
                    /*
                     * Do whatever you need to grant explicit rights
                     * to this particular proxy certificate, usually
                     * by pulling them from some database.  If there
                     * are none to be found, clear all rights (making
                     * this and any subsequent proxy certificate void
                     * of any rights).
                     */
                    memset(rights->rights, 0, sizeof(rights->rights));
                    break;
                case NID_id_ppl_inheritAll:
                    /*
                     * This is basically a NOP, we simply let the
                     * current rights stand as they are.
                     */
                    break;
                default:
                    /*
                     * This is usually the most complex section of
                     * code.  You really do whatever you want as long
                     * as you follow RFC 3820.  In the example we use
                     * here, the simplest thing to do is to build
                     * another, temporary bit array and fill it with
                     * the rights granted by the current proxy
                     * certificate, then use it as a mask on the
                     * accumulated rights bit array, and voilà, you
                     * now have a new accumulated rights bit array.
                     */
                    {
                        int i;
                        YOUR_RIGHTS tmp_rights;
                        memset(tmp_rights.rights, 0,
                               sizeof(tmp_rights.rights));

                        /*
                         * process_rights() is supposed to be a
                         * procedure that takes a string and its
                         * length, interprets it and sets the bits
                         * in the YOUR_RIGHTS pointed at by the
                         * third argument.
                         */
                        process_rights((char *) pci->proxyPolicy->policy->data,
                                       pci->proxyPolicy->policy->length,
                                       &tmp_rights);

                        for(i = 0; i < total_rights / 8; i++)
                            rights->rights[i] &= tmp_rights.rights[i];
                    }
                    break;
                }
                PROXY_CERT_INFO_EXTENSION_free(pci);
            } else if (!(X509_get_extension_flags(xs) & EXFLAG_CA)) {
                /* We have an EE certificate, let's use it to set default! */
                YOUR_RIGHTS *rights =
                    (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx,
                        get_proxy_auth_ex_data_idx(ctx));

                /*
                 * The following procedure finds out what rights the
                 * owner of the current certificate has, and sets them
                 * in the YOUR_RIGHTS structure pointed at by the
                 * second argument.
                 */
                set_default_rights(xs, rights);
            }
        }
        return ok;
    }

    static int my_X509_verify_cert(X509_STORE_CTX *ctx,
                                   YOUR_RIGHTS *needed_rights)
    {
        int ok;
        int (*save_verify_cb)(int ok,X509_STORE_CTX *ctx) =
            X509_STORE_CTX_get_verify_cb(ctx);
        YOUR_RIGHTS rights;

        X509_STORE_CTX_set_verify_cb(ctx, verify_callback);
        X509_STORE_CTX_set_ex_data(ctx, get_proxy_auth_ex_data_idx(ctx),
                                   &rights);
        X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
        ok = X509_verify_cert(ctx);

        if (ok == 1) {
            ok = check_needed_rights(rights, needed_rights);
        }

        X509_STORE_CTX_set_verify_cb(ctx, save_verify_cb);

        return ok;
    }

If you use SSL or TLS, you can easily set up a callback to have the
certificates checked properly, using the code above:

    SSL_CTX_set_cert_verify_callback(s_ctx, my_X509_verify_cert,
                                     &needed_rights);

=head1 NOTES

To this date, it seems that proxy certificates have only been used in
environments that are aware of them, and no one seems to have
investigated how they can be used or misused outside of such an
environment.

For that reason, OpenSSL requires that applications aware of proxy
certificates must also make that explicit.

B<subjectAltName> and B<issuerAltName> are forbidden in proxy
certificates, and this is enforced in OpenSSL.  The subject must be
the same as the issuer, with one commonName added on.

=head1 SEE ALSO

L<X509_STORE_CTX_set_flags(3)>,
L<X509_STORE_CTX_set_verify_cb(3)>,
L<X509_VERIFY_PARAM_set_flags(3)>,
L<SSL_CTX_set_cert_verify_callback(3)>,
L<openssl-req(1)>, L<openssl-x509(1)>,
L<RFC 3820|https://tools.ietf.org/html/rfc3820>

=head1 COPYRIGHT

Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License").  You may not use
this file except in compliance with the License.  You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.

=cut
