All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.authlete.cose.COSEOKPKey Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2023 Authlete, Inc.
 *
 * 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
 *
 *     https://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.
 */
package com.authlete.cose;


import java.util.List;
import java.util.Map;
import com.authlete.cbor.CBORByteArray;
import com.authlete.cbor.CBORItem;
import com.authlete.cbor.CBORPair;
import com.authlete.cbor.CBORPairsBuilder;
import com.authlete.cbor.CBORString;
import com.authlete.cose.constants.COSEEllipticCurves;
import com.authlete.cose.constants.COSEKeyTypeParameters;


/**
 * OKP Key
 *
 * @since 1.1
 *
 * @see RFC 9052, 7. Key Objects
 *
 * @see RFC 9053, 2.2. Edwards-Curve Digital Signature Algorithm (EdDSA)
 *
 * @see IANA: COSE Key Common Parameters
 *
 * @see IANA: COSE Key Type Parameters
 *
 * @see IANA: COSE Key Types
 *
 * @see IANA: COSE Elliptic Curves
 */
public class COSEOKPKey extends COSEKey
{
    private Object crv;
    private byte[] x;
    private byte[] d;


    /**
     * A constructor with key parameters.
     *
     * @param pairs
     *         Key parameters.
     */
    public COSEOKPKey(List pairs)
    {
        super(pairs);

        validateParameters(pairs);
    }

    private void validateParameters(List pairs)
    {
        for (CBORPair pair : pairs)
        {
            validateParameter(pair);
        }
    }


    private void validateParameter(CBORPair pair)
    {
        Object label = pair.getKey();

        // If the label is not an integer that is in the range of Java 'int'.
        if (!(label instanceof Integer))
        {
            // Unknown label.
            return;
        }

        // Validate the value if the label is a known one.
        validateKnownParameter((Integer)label, pair.getValue());
    }


    private void validateKnownParameter(int label, CBORItem value)
    {
        switch (label)
        {
            case COSEKeyTypeParameters.OKP_CRV:
                crv = validateCrv(value);
                break;

            case COSEKeyTypeParameters.OKP_X:
                x = validateX(value);
                break;

            case COSEKeyTypeParameters.OKP_D:
                d = validateD(value);
                break;

            default:
                break;
        }
    }


    private static Object validateCrv(CBORItem value)
    {
        if (isInteger(value) || (value instanceof CBORString))
        {
            return getRawValue(value);
        }

        throw new IllegalArgumentException(
                "crv (-1) must be an integer or a text string.");
    }


    private static byte[] validateX(CBORItem value)
    {
        if (value instanceof CBORByteArray)
        {
            return (byte[])getRawValue(value);
        }

        throw new IllegalArgumentException(
                "x (-2) must be a byte string.");
    }


    private static byte[] validateD(CBORItem value)
    {
        if (value instanceof CBORByteArray)
        {
            return (byte[])getRawValue(value);
        }

        throw new IllegalArgumentException(
                "d (-4) must be a byte string.");
    }


    @Override
    public boolean isPrivate()
    {
        return (d != null);
    }


    @Override
    protected void addJwkProperties(Map map)
    {
        // crv
        if (crv != null)
        {
            map.put("crv", toJwkCrv(crv));
        }

        // x
        if (x != null)
        {
            map.put("x", encodeByBase64Url(x));
        }

        // d
        if (d != null)
        {
            map.put("d", encodeByBase64Url(d));
        }
    }


    /**
     * Get the curve (the value of the {@code crv} parameter).
     *
     * 

* The type of the value is an integer ({@code int}, {@code long} or * {@code BigInteger}) or a string ({@code String}). *

* * @return * The curve. * * @see IANA: COSE Elliptic Curves */ public Object getCrv() { return crv; } /** * Get the public key (the value of the {@code x} parameter). * * @return * The public key. */ public byte[] getX() { return x; } /** * Get the private key (the value of the {@code d} parameter). * * @return * The private key. */ public byte[] getD() { return d; } static void addCoseKtySpecificParameters( CBORPairsBuilder builder, Map jwk) throws COSEException { // crv addCoseOKPCrv(builder, jwk); // x addCoseOKPX(builder, jwk); // d addCoseOKPD(builder, jwk); } private static void addCoseOKPCrv( CBORPairsBuilder builder, Map jwk) throws COSEException { String crv = extractStringProperty(jwk, "crv", /* required */ false); if (crv == null) { return; } int value = COSEEllipticCurves.getValueByName(crv); if (value == 0) { throw new COSEException(String.format( "The curve '%s' is not supported.", crv)); } builder.add(COSEKeyTypeParameters.OKP_CRV, value); } private static void addCoseOKPX( CBORPairsBuilder builder, Map jwk) throws COSEException { byte[] value = extractBase64UrlProperty(jwk, "x", /* required */ false); builder.addUnlessNull(COSEKeyTypeParameters.OKP_X, value); } private static void addCoseOKPD( CBORPairsBuilder builder, Map jwk) throws COSEException { byte[] value = extractBase64UrlProperty(jwk, "d", /* required */ false); builder.addUnlessNull(COSEKeyTypeParameters.OKP_D, value); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy