// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.v23.security;

import com.google.common.collect.ImmutableList;
import io.v.v23.context.VContext;
import io.v.v23.security.access.Permissions;
import io.v.v23.security.access.PermissionsAuthorizer;
import io.v.v23.verror.VException;
import io.v.v23.vom.VomUtil;
import org.joda.time.DateTime;

import java.lang.reflect.Type;
import java.security.*;
import java.security.interfaces.ECPublicKey;
import java.util.Arrays;
import java.util.List;

/**
 * Various functions used for creating and managing Vanadium security primitives.
 */
public class VSecurity {
    private static native String[] nativeGetRemoteBlessingNames(VContext context, Call call)
            throws VException;
    private static native String[] nativeGetLocalBlessingNames(VContext context, Call call)
            throws VException;
    private static native String[] nativeGetBlessingNames(VPrincipal principal, Blessings blessings)
            throws VException;
    private static native String[] nativeGetSigningBlessingNames(VContext context,
            VPrincipal principal, Blessings blessings) throws VException;
    private static native void nativeAddToRoots(VPrincipal principal, Blessings blessings)
            throws VException;


    /**
     * Creates a new instance of {@link VSigner} using the provided public/private key pair.
     * <p>
     * The returned {@link VSigner} respests the location of the private key: if the key
     * is stored in a safe place (e.g., hardware token), it will remain secure.
     *
     * @param  privKey private key
     * @param  pubKey  corresponding public key
     * @return         new instance of {@link VSigner} that uses the provided key pair to
     *                 do the signing
     */
    public static VSigner newSigner(PrivateKey privKey, ECPublicKey pubKey) {
        return new ECDSASigner(privKey, pubKey);
    }

    /**
     * Mints a new private key and creates a {@link VSigner} based on this key.  The key is stored
     * in the clear in memory of the running process.
     */
    public static VSigner newInMemorySigner() throws VException {
        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
            keyGen.initialize(256);
            KeyPair keyPair = keyGen.generateKeyPair();
            PrivateKey privKey = keyPair.getPrivate();
            ECPublicKey pubKey = (ECPublicKey) keyPair.getPublic();
            return new ECDSASigner(privKey, pubKey);
        } catch (NoSuchAlgorithmException e) {
            throw new VException("Couldn't mint private key: " + e.getMessage());
        }
    }

    /**
     * Mints a new private key and generates a principal based on this key, storing its
     * blessing roots and blessing store in memory.
     *
     * @return                 in-memory principal using the newly minted private key
     * @throws VException      if the principal couldn't be created
     */
    public static VPrincipal newPrincipal() throws VException {
        return VPrincipalImpl.create();
    }

    /**
     * Creates a principal using the provided signer, storing its blessing roots and
     * blessing store in memory.
     *
     * @param  signer          signer to be used by the new principal
     * @return                 in-memory principal using the provided signer
     * @throws VException      if the principal couldn't be created
     */
    public static VPrincipal newPrincipal(VSigner signer) throws VException {
        return VPrincipalImpl.create(signer);
    }

    /**
     * Creates a principal using the provided signer, blessing store, and blessing roots.  If the
     * provided store is {@code null}, the principal will use a store whose every opration will
     * fail.  If the provided roots are {@code null}, the principal will not trust any public keys
     * and all subsequent {@link VSecurity#addToRoots} operations with that principal will fail.
     *
     * @param  signer signer to be used by the principal
     * @param  store  blessing store to be used by the principal
     * @param  roots  blessing roots to be used by the principal
     * @return        newly created principal
     */
    public static VPrincipal newPrincipal(VSigner signer, BlessingStore store, BlessingRoots roots)
        throws VException {
        return VPrincipalImpl.create(signer, store, roots);
    }

    /**
     * Reads the entire state for a principal (i.e., private key, blessing roots, blessing store)
     * from the provided directory {@code dir} and commits all state changes to the same directory.
     * <p>
     * If the directory does not contain state, a new private key is minted and all state of the
     * principal is committed to {@code dir}. If the directory does not exist, it is created.
     *
     * @param  passphrase      passphrase used to encrypt the private key; if empty, no encryption
     *                         is done
     * @param  dir             directory where the state for a principal is to be persisted
     * @return                 principal whose state is persisted in the provided directory
     * @throws VException      if the principal couldn't be created
     */
    public static VPrincipal newPersistentPrincipal(String passphrase, String dir)
            throws VException {
        return VPrincipalImpl.createPersistent(passphrase, dir);
    }

    /**
     * Creates a new principal using the provided signer and a partial state (i.e., blessing roots,
     * blessing store) that is read from the provided directory {@code dir}.  Changes to the
     * partial state are persisted and commited to the same directory.  The provided signer isn't
     * persisted: the caller is expected to persist it separately.
     * <p>
     * If the directory does not contain any partial state, a new partial state instances are
     * created and subsequently commited to {@code dir}.  If the directory does not exist, it
     * is created.
     *
     * @param  signer          signer to be used by the new principal
     * @param  dir             directory where the partial state for a principal is to be persisted
     * @return                 principal whose partial state is persisted in the provided directory
     * @throws VException      if the principal couldn't be created
     */
    public static VPrincipal newPersistentPrincipal(VSigner signer, String dir)
        throws VException {
        return VPrincipalImpl.createPersistent(signer, dir);
    }

    /**
     * Returns a {@link Blessings} object that carries the union of the provided blessings.
     * All provided blessings must have the same public key.  Returns {@code null} if invoked
     * without arguments.
     *
     * @param  blessings       blessings that will be merged
     * @return                 the union of the provided blessings
     * @throws VException      if there was an error creating an union
     */
    public static Blessings unionOfBlessings(Blessings... blessings) throws VException {
        return Blessings.createUnion(blessings);
    }

    /**
     * Returns a validated set of blessing names presented by the remote end of a call.
     * <p>
     * These returned blessings (strings) are guaranteed to:
     * <p><ol>
     *     <li>Satisfy all the caveats given the call.</li>
     *     <li>Be rooted in {@code call.localPrincipal().roots()}.</li>
     * </ol>
     * <p>
     * Caveats are considered satisfied in the given call if the {@link CaveatValidator}
     * implementation can be found in the address space of the caller and
     * {@link CaveatValidator#validate validate} doesn't throw an exception.
     *
     * @param  context  vanadium context
     * @param  call     security-related state associated with the call
     * @return          validated set of blessing names presented by the remote end of a call
     *                  (possibly empty, but never {@code null})
     */
    public static String[] getRemoteBlessingNames(VContext context, Call call) {
        try {
            return nativeGetRemoteBlessingNames(context, call);
        } catch (VException e) {
            throw new RuntimeException("Couldn't get blessings for call", e);
        }
    }

    /**
     * Returns the set of human-readable blessing names presented by the local end of the call.
     * <p>
     * This is merely a convenience over
     * {@code getBlessingNames(call.localPrincipal(), call.localBlessings())}
     *
     * @param  context vanadium context
     * @param  call    security-related state associated with the call
     * @return         set of blessing names presented by the local end of the call
     *                 (possibly empty, but never {@code null})
     */
    public static String[] getLocalBlessingNames(VContext context, Call call) {
        try {
            return nativeGetLocalBlessingNames(context, call);
        } catch (VException e) {
            throw new RuntimeException("Couldn't get blessings for call", e);
        }
    }

    /**
     * Returns the set of human-readable blessing names encapsulated in blessings.
     * <p>
     * The returned names are guaranteed to be rooted in {@link VPrincipal#roots}
     * though caveats may not be validated.
     * <p>
     * The blessings must be bound to the provided principal. There is
     * intentionally not API to obtain blessing names bound to other principals
     * by ignoring caveats.  This is to prevent accidental authorization based
     * on potentially invalid blessing names (since caveats are not validated).
     *
     * @param principal principal to which the provided blessings are bound
     * @param blessings the blessings whose names are to be extracted
     * @return          set of blessing names bound to principal, encapsulated
     *                  in blessings (possibly empty, but never {@code null})
     */
    public static String[] getBlessingNames(VPrincipal principal, Blessings blessings) {
        try {
            return nativeGetBlessingNames(principal, blessings);
        } catch (VException e) {
            throw new RuntimeException("Couldn't get blessing names", e);
        }
    }

    /**
     * Returns the set of validated human-readable signing blessing names encapsulated in the
     * provided blessings object, as determined by the provided principal.  Only names that are
     * available for signing are returned by this method, even though the given blessings object
     * might have more blessing names that are valid at the time. (The name on a certificate chain
     * is valid if all the caveats on the chain are signing caveats, and the chain's validity can
     * be checked by the given principal).
     * <p>
     * The blessing names are guaranteed to be rooted in {@code call.localPrincipal().roots()}.
     * <p>
     * This method does not validate caveats on the blessing names.
     *
     * @param  context      vanadium context
     * @param  principal    vanadium principal
     * @param  blessings    vanadium blessings
     * @return              validated set of human-readable blessing names encapsulated in the
     *                      provided signing blessings object, as determined by the provided
     *                      {@link VPrincipal} (possibly empty, but never {@code null})
     */
    public static String[] getSigningBlessingNames(VContext context, VPrincipal principal,
            Blessings blessings) {
        try {
            return nativeGetSigningBlessingNames(context, principal, blessings);
        } catch (VException e) {
            throw new RuntimeException("Couldn't get signing blessing names", e);
        }
    }

    /**
     * Returns a caveat that requires validation by the validator corresponding to the
     * given descriptor and uses the provided parameter.
     *
     * @param  desc            caveat descriptor
     * @param  param           caveat parameter used by the associated validator
     * @return                 caveat that requires validation by the validator corresponding to the
     *                         given descriptor and uses the provided parameter
     * @throws VException      if the caveat couldn't be created
     */
    public static Caveat newCaveat(CaveatDescriptor desc, Object param) throws VException {
        byte[] paramVOM = VomUtil.encode(param, desc.getParamType().getTypeObject());
        return new Caveat(desc.getId(), paramVOM);
    }

    /**
     * Returns a caveat that validates iff the current time is before the provided time.
     *
     * @param  time            time before which the caveat validates
     * @return                 caveat that validates if the current time is before the provided time
     * @throws VException      if the caveat couldn't be created
     */
    public static Caveat newExpiryCaveat(DateTime time) throws VException {
        return newCaveat(Constants.EXPIRY_CAVEAT, time);
    }

    /**
     * Returns a caveat that validates iff the method being invoked by the peer is listed in an
     * argument to this function.
     *
     * @param  method            name of the method for which this caveat should validate
     * @param  additionalMethods additional method names for which this caveat should validate
     * @return                   caveat that validates iff the method being invoked by the peer is
     *                           one of the provided methods
     * @throws VException        if the caveat couldn't be created
     */
    public static Caveat newMethodCaveat(String method, String... additionalMethods)
            throws VException {
        List<String> methods = ImmutableList.<String>builder()
                .add(method)
                .add(additionalMethods)
                .build();
        return newCaveat(Constants.METHOD_CAVEAT, methods);
    }

    /**
     * Returns a caveat that never fails to validate. This is useful only for providing
     * unconstrained blessings to another principal.
     *
     * @return a caveat that never fails to validate
     */
    public static Caveat newUnconstrainedUseCaveat() throws VException {
        return newCaveat(Constants.CONST_CAVEAT, true);
    }

    /**
     * Returns a new security call that uses the provided params.
     *
     * @param params call params
     * @return       new security call that uses the provided params
     */
    public static Call newCall(CallParams params) {
        return new CallParamsImpl(params);
    }

    /**
     * Returns an authorizer that subscribes to an authorization policy where access is granted if
     * the remote end presents blessings included in the Access Control Lists (ACLs) associated with
     * the set of relevant tags.
     * <p>
     * See {@link io.v.v23.security.access.PermissionsAuthorizer} for a more detailed description
     * of this authorizer.
     *
     * @param  acls            ACLs containing authorization rules
     * @param  type            type of the method tags this authorizer checks
     * @return                 a newly created authorizer
     * @throws VException      if the authorizer couldn't be created
     */
    public static Authorizer newPermissionsAuthorizer(Permissions acls, Type type)
        throws VException {
        return PermissionsAuthorizer.create(acls, type);
    }

    /**
     * Returns an authorizer that allows all requests.
     */
    public static Authorizer newAllowEveryoneAuthorizer() {
        return new Authorizer() {
            @Override
            public void authorize(VContext ctx, Call call) throws VException {
                // do nothing
            }
        };
    }

    /**
     * Verifies the provides signature of the given message, using the supplied public key.
     *
     * @param  sig             signature in the Vanadium format
     * @param  key             public key
     * @param  message         message whose signature is verified
     * @throws VException      iff the signature doesn't verify
     */
    public static void verifySignature(VSignature sig, ECPublicKey key, byte[] message)
        throws VException {
        String vHashAlgorithm = sig.getHash().getValue();
        String verifyAlgorithm = CryptoUtil.javaSigningAlgorithm(vHashAlgorithm);
        try {
            message = CryptoUtil.messageDigest(vHashAlgorithm, message, sig.getPurpose(), key);
            byte[] jSig = CryptoUtil.javaSignature(sig);
            java.security.Signature verifier = java.security.Signature.getInstance(verifyAlgorithm);
            verifier.initVerify(key);
            verifier.update(message);
            if (!verifier.verify(jSig)) {
                throw new VException("Signature doesn't verify.");
            }
        } catch (NoSuchAlgorithmException e) {
            throw new VException("Verifying algorithm " + verifyAlgorithm +
                    " not supported by the runtime: " + e.getMessage());
        } catch (InvalidKeyException e) {
            throw new VException("Invalid private key: " + e.getMessage());
        } catch (SignatureException e) {
            throw new VException(
                "Invalid signing data [ " + Arrays.toString(message) + " ]: " + e.getMessage());
        }
    }

    /**
     * Marks the root principals of all blessing chains represented by {@code blessings} as an
     * authority on blessing chains beginning at that root.
     * <p>
     * For example, if {@code blessings} represents the blessing chains
     * {@code ["alice/friend/spouse", "charlie/family/daughter"]} then {@code addToRoots(blessing)}
     * will mark the root public key of the chain {@code "alice/friend/bob"} as the as authority on
     * all blessings that match the pattern {@code "alice/..."}, and root public key of the chain
     * {@code "charlie/family/daughter"} as an authority on all blessings that match the pattern
     * {@code "charlie/..."}.
     *
     * @param  principal       the principal whose {@link BlessingRoots} object should be edited
     * @param  blessings       blessings to be used as authorities on blessing chains beginning at
     *                         those roots
     * @throws VException      if there was an error assigning the said authorities
     */
    public static void addToRoots(VPrincipal principal, Blessings blessings) throws VException {
        nativeAddToRoots(principal, blessings);
    }

    private VSecurity() {}
}
