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

io.jsonwebtoken.impl.security.OctetPrivateJwkFactory Maven / Gradle / Ivy

/*
 * Copyright © 2023 jsonwebtoken.io
 *
 * 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.
 */
package io.jsonwebtoken.impl.security;

import io.jsonwebtoken.impl.lang.ParameterReadable;
import io.jsonwebtoken.impl.lang.RequiredParameterReader;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.lang.Strings;
import io.jsonwebtoken.security.InvalidKeyException;
import io.jsonwebtoken.security.OctetPrivateJwk;
import io.jsonwebtoken.security.OctetPublicJwk;

import java.security.PrivateKey;
import java.security.PublicKey;

public class OctetPrivateJwkFactory extends OctetJwkFactory> {

    public OctetPrivateJwkFactory() {
        super(PrivateKey.class, DefaultOctetPrivateJwk.PARAMS);
    }

    @Override
    protected boolean supportsKeyValues(JwkContext ctx) {
        return super.supportsKeyValues(ctx) && ctx.containsKey(DefaultOctetPrivateJwk.D.getId());
    }

    @Override
    protected OctetPrivateJwk createJwkFromKey(JwkContext ctx) {
        PrivateKey key = Assert.notNull(ctx.getKey(), "PrivateKey cannot be null.");
        EdwardsCurve crv = EdwardsCurve.forKey(key);

        PublicKey pub = ctx.getPublicKey();
        if (pub != null) {
            if (!crv.equals(EdwardsCurve.forKey(pub))) {
                String msg = "Specified Edwards Curve PublicKey does not match the specified PrivateKey's curve.";
                throw new InvalidKeyException(msg);
            }
        } else { // not supplied - try to generate it:
            pub = EdwardsCurve.derivePublic(key);
        }

        // If a JWK fingerprint has been requested to be the JWK id, ensure we copy over the one computed for the
        // public key per https://www.rfc-editor.org/rfc/rfc7638#section-3.2.1
        boolean copyId = !Strings.hasText(ctx.getId()) && ctx.getIdThumbprintAlgorithm() != null;
        JwkContext pubCtx = OctetPublicJwkFactory.INSTANCE.newContext(ctx, pub);
        OctetPublicJwk pubJwk = OctetPublicJwkFactory.INSTANCE.createJwk(pubCtx);
        ctx.putAll(pubJwk);
        if (copyId) {
            ctx.setId(pubJwk.getId());
        }

        //now add the d value
        byte[] d = crv.getKeyMaterial(key);
        Assert.notEmpty(d, "Edwards PrivateKey 'd' value cannot be null or empty.");
        //TODO: assert that the curve contains the specified key
        put(ctx, DefaultOctetPrivateJwk.D, d);

        return new DefaultOctetPrivateJwk<>(ctx, pubJwk);
    }

    @Override
    protected OctetPrivateJwk createJwkFromValues(JwkContext ctx) {
        ParameterReadable reader = new RequiredParameterReader(ctx);
        EdwardsCurve curve = getCurve(reader);
        //TODO: assert that the curve contains the specified key

        // public values are required, so assert them:
        JwkContext pubCtx = new DefaultJwkContext<>(DefaultOctetPublicJwk.PARAMS, ctx);
        OctetPublicJwk pubJwk = OctetPublicJwkFactory.INSTANCE.createJwkFromValues(pubCtx);

        byte[] d = reader.get(DefaultOctetPrivateJwk.D);
        PrivateKey key = curve.toPrivateKey(d, ctx.getProvider());
        ctx.setKey(key);

        return new DefaultOctetPrivateJwk<>(ctx, pubJwk);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy