# This code is made available to you under your choice of the following sets
# of licensing terms:
###############################################################################
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
###############################################################################
# Copyright 2013 Mozilla Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function
import argparse
import itertools
import sys


def base128(value):
    """
    Given an integral value, returns an array of the base-128 representation
    of that value, with all but the last byte having the high bit set as
    required by the DER rules for the nodes of an OID after the first two
    bytes.

    >>> base128(1)
    [1]
    >>> base128(10045)
    [206, 61]
    """

    if value < 0:
        raise ValueError("An OID must have only positive-value nodes.")

    # least significant byte has highest bit unset
    result = [value % 0x80]
    value /= 0x80

    while value != 0:
        result = [0x80 | (value % 0x80)] + result
        value /= 0x80

    return result


def dottedOIDToEncodedArray(dottedOID):
    """
    Takes a dotted OID string (e.g. '1.2.840.10045.4.3.4') as input, and
    returns an array that contains the DER encoding of its value, without
    the tag and length (e.g. [0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04]).
    """
    nodes = [int(x) for x in dottedOID.strip().split(".")]
    if len(nodes) < 2:
        raise ValueError("An OID must have at least two nodes.")
    if not (0 <= nodes[0] <= 2):
        raise ValueError("The first node of an OID must be 0, 1, or 2.")
    if not (0 <= nodes[1] <= 39):
        # XXX: Does this restriction apply when the first part is 2?
        raise ValueError("The second node of an OID must be 0-39.")
    firstByte = (40 * nodes[0]) + nodes[1]
    restBase128 = [base128(x) for x in nodes[2:]]
    return [firstByte] + list(itertools.chain.from_iterable(restBase128))


def dottedOIDToCArray(dottedOID, mode):
    """
    Takes a dotted OID string (e.g. '1.2.840.10045.4.3.4') as input, and
    returns a string that contains the hex encoding of the OID in C++ literal
    notation, e.g. '0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04'.
    """
    bytes = dottedOIDToEncodedArray(dottedOID)

    if mode != "value" and mode != "prefixdefine":
        bytes = [0x06, len(bytes)] + bytes

    if mode == "alg":
        # Wrap the DER-encoded OID in a SEQUENCE to create an
        # AlgorithmIdentifier with no parameters.
        bytes = [0x30, len(bytes)] + bytes

    return ", ".join(["0x%.2x" % b for b in bytes])


def specNameToCName(specName):
    """
    Given an string containing an ASN.1 name, returns a string that is a valid
    C++ identifier that is as similar to that name as possible. Since most
    ASN.1 identifiers used in PKIX specifications are legal C++ names except
    for containing hyphens, this function just converts the hyphens to
    underscores. This may need to be improved in the future if we encounter
    names with other funny characters.
    """
    return specName.replace("-", "_")


def toCode(programName, specName, dottedOID, mode):
    """
    Given an ASN.1 name and a string containing the dotted representation of an
    OID, returns a string that contains a C++ declaration for a named constant
    that contains that OID value. If mode is "value" then only the value of
    the OID (without the tag or length) will be included in the output. If mode
    is "tlv" then the value will be prefixed with the tag and length. If mode
    is "alg" then the value will be a complete der-encoded AlgorithmIdentifier
    with no parameters.

    This:

        toCode("DottedOIDToCode.py", "ecdsa-with-SHA512", "1.2.840.10045.4.3.4",
               "value")

    would result in a string like:

        // python DottedOIDToCode.py ecdsa-with-SHA512 1.2.840.10045.4.3.4
        static const uint8_t ecdsa_with_SHA512[] = {
          0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04
        };

    This:

        toCode("DottedOIDToCode.py", "ecdsa-with-SHA512", "1.2.840.10045.4.3.4",
               "tlv")

    would result in a string like:

        // python DottedOIDToCode.py --tlv ecdsa-with-SHA512 1.2.840.10045.4.3.4
        static const uint8_t tlv_ecdsa_with_SHA512[] = {
          0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04
        };

    This:

        toCode("DottedOIDToCode.py", "ecdsa-with-SHA512", "1.2.840.10045.4.3.4",
               "alg")

    would result in a string like:

        // python DottedOIDToCode.py --alg ecdsa-with-SHA512 1.2.840.10045.4.3.4
        static const uint8_t alg_ecdsa_with_SHA512[] = {
          0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04
        };

    This:

        toCode("DottedOIDToCode.py", "PREFIX_1_2_840_10045", "1.2.840.10045",
               "prefixdefine")

    would result in a string like this (note the lack of indention):

      // python DottedOIDToCode.py --prefixdefine PREFIX_1_2_840_10045 1.2.840.10045
      #define PREFIX_1_2_840_10045 0x2a, 0x86, 0x48, 0xce, 0x3d
    """
    programNameWithOptions = programName

    if mode == "prefixdefine":
        programNameWithOptions += " --prefixdefine"
        varName = specName
        return ("// python %s %s %s\n" +
                "#define %s %s\n") % (programNameWithOptions, specName,
                                      dottedOID, varName,
                                      dottedOIDToCArray(dottedOID, mode))

    varName = specNameToCName(specName)
    if mode == "tlv":
        programNameWithOptions += " --tlv"
        varName = "tlv_" + varName
    elif mode == "alg":
        programNameWithOptions += " --alg"
        varName = "alg_" + varName
    elif mode == "prefixdefine":
        programNameWithOptions += " --alg"
        varName = varName

    return ("  // python %s %s %s\n" +
            "  static const uint8_t %s[] = {\n" +
            "    %s\n" +
            "  };\n") % (programNameWithOptions, specName, dottedOID, varName,
                         dottedOIDToCArray(dottedOID, mode))


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Generate code snippets to handle OIDs in C++",
        epilog="example: python %s ecdsa-with-SHA1 1.2.840.10045.4.1"
        % sys.argv[0])
    group = parser.add_mutually_exclusive_group()
    group.add_argument("--tlv", action='store_true',
                       help="Wrap the encoded OID value with the tag and length")
    group.add_argument("--alg", action='store_true',
                       help="Wrap the encoded OID value in an encoded SignatureAlgorithm")
    group.add_argument("--prefixdefine", action='store_true',
                       help="generate a OID prefix #define")
    parser.add_argument("name",
                        help="The name given to the OID in the specification")
    parser.add_argument("dottedOID", metavar="dotted-oid",
                        help="The OID value, in dotted notation")

    args = parser.parse_args()
    if args.alg:
        mode = 'alg'
    elif args.tlv:
        mode = 'tlv'
    elif args.prefixdefine:
        mode = 'prefixdefine'
    else:
        mode = 'value'

    print(toCode(sys.argv[0], args.name, args.dottedOID, mode))
