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

be.atbash.ee.security.octopus.keys.AtbashKey Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2017-2022 Rudy De Busscher (https://www.atbash.be)
 *
 * 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 be.atbash.ee.security.octopus.keys;

import be.atbash.ee.security.octopus.keys.selector.AsymmetricPart;
import be.atbash.ee.security.octopus.keys.selector.SecretKeyType;
import be.atbash.ee.security.octopus.nimbus.jwk.Curve;
import be.atbash.ee.security.octopus.nimbus.jwk.KeyType;
import be.atbash.util.PublicAPI;
import be.atbash.util.resource.ResourceUtil;

import java.net.MalformedURLException;
import java.net.URL;
import java.security.Key;
import java.security.interfaces.ECKey;
import java.security.interfaces.RSAKey;

// Useful info https://www.cem.me/pki/
@PublicAPI
public class AtbashKey {

    private final String keyId;
    private final SecretKeyType secretKeyType;
    private final Key key;

    /**
     * Creates an AtbashKey from the cryptographic key and the Key id. When the key Id starts with a classpath,
     * File or URL prefix, the kid is based on the 'resource' name.
     *
     * @param kid The identification
     * @param key The cryptographic key
     */
    public AtbashKey(String kid, Key key) {

        if (key == null) {
            throw new IllegalArgumentException("Parameter key cannot be null");
        }
        if (kid == null) {
            throw new IllegalArgumentException("Parameter kid cannot be null");
        }

        keyId = defineKeyId(kid);
        this.key = key;
        secretKeyType = SecretKeyType.fromKey(key);
    }

    public String getKeyId() {
        return keyId;
    }

    public SecretKeyType getSecretKeyType() {
        return secretKeyType;
    }

    public Key getKey() {
        return key;
    }

    public String getSpecification() {
        StringBuilder result = new StringBuilder();
        if (KeyType.EC.equals(secretKeyType.getKeyType())) {
            Curve curve = ECCurveHelper.getCurve((ECKey) key);
            result.append("Curve name : ").append(curve == null ? "unknown" : curve.getName());
        }
        if (KeyType.RSA.equals(secretKeyType.getKeyType())) {
            RSAKey rsaKey = (RSAKey) key;
            result.append("key length : ").append(rsaKey.getModulus().bitLength());
        }
        if (KeyType.OCT.equals(secretKeyType.getKeyType())) {
            result.append("key length : ").append(key.getEncoded().length * 8);
        }
        if (KeyType.OKP.equals(secretKeyType.getKeyType())) {
            result.append("Curve name : Ed25519");  // TODO Support for other EdDSA algorithms.
        }
        return result.toString();
    }

    private String defineKeyId(String value) {
        String result = value;
        if (value.startsWith(ResourceUtil.CLASSPATH_PREFIX)) {
            result = defineKeyId(result, ResourceUtil.CLASSPATH_PREFIX);
        }
        if (value.startsWith(ResourceUtil.FILE_PREFIX)) {
            result = defineKeyId(result, ResourceUtil.FILE_PREFIX);
        }
        if (value.startsWith(ResourceUtil.URL_PREFIX)) {
            try {
                result = result.substring(ResourceUtil.URL_PREFIX.length());
                URL url = new URL(result);
                result = defineKeyId(url.getPath(), "");
            } catch (MalformedURLException e) {
                // Use de value without prefix as key
            }
        }
        return result;
    }

    private String defineKeyId(String result, String prefix) {
        int prefixStart = result.lastIndexOf('.');
        if (prefixStart != -1) {
            result = result.substring(0, prefixStart);
        }
        result = result.substring(prefix.length());
        return result;
    }

    public boolean isMatch(String keyId, AsymmetricPart asymmetricPart) {
        return this.keyId.equals(keyId) && secretKeyType.getAsymmetricPart() == asymmetricPart;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        AtbashKey atbashKey = (AtbashKey) o;

        if (!keyId.equals(atbashKey.keyId)) {
            return false;
        }
        return secretKeyType.equals(atbashKey.secretKeyType);
    }

    @Override
    public int hashCode() {
        int result = keyId.hashCode();
        result = 31 * result + secretKeyType.hashCode();
        return result;
    }

    public static class AtbashKeyBuilder {
        private String keyId;
        private Key key;

        public AtbashKeyBuilder withKeyId(String keyId) {
            this.keyId = keyId;
            return this;
        }

        public AtbashKeyBuilder withKey(Key key) {
            this.key = key;
            return this;
        }

        public AtbashKey build() {
            return new AtbashKey(keyId, key);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy