/************************************************************************* * (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. ************************************************************************/ package com.eucalyptus.tokens.oidc; import java.io.IOException; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.List; import javax.annotation.Nonnull; import com.eucalyptus.util.Json; import com.eucalyptus.util.Pair; import com.eucalyptus.util.Strings; import com.fasterxml.jackson.databind.JsonNode; import com.google.common.base.MoreObjects; import javaslang.control.Option; /** * JSON Web Key (JWK) * https://tools.ietf.org/html/rfc7517 */ public abstract class JsonWebKey { private final String alg; private final Option<String> kid; private final Option<String> use; private final Option<List<String>> keyOps; private final Option<List<String>> x5c; // base64 encoded certificate chain JsonWebKey( final String alg, final Option<String> kid, final Option<String> use, final Option<List<String>> keyOps, final Option<List<String>> x5c ) { this.alg = alg; this.kid = kid; this.use = use; this.keyOps = keyOps; this.x5c =x5c; } @Nonnull public abstract String getKty( ); @Nonnull public String getAlg( ) { return alg; } @Nonnull public Option<String> getKid( ) { return kid; } @Nonnull public Option<String> getUse( ) { return use; } @Nonnull public Option<List<String>> getKeyOps( ) { return keyOps; } @Nonnull public Option<List<String>> getX5c( ) { return x5c; } public Pair<String,Option<String>> key( ) { return key( getKty( ), getKid( ) ); } public static Pair<String,Option<String>> key( final Class<? extends JsonWebKey> type, final Option<String> kid ) { return Pair.pair( type( type ), kid ); } public static Pair<String,Option<String>> key( final String type, final Option<String> kid ) { return Pair.pair( type, kid ); } public String toString( ) { return MoreObjects.toStringHelper( JsonWebKey.class ) .add( "kty", getKty( ) ) .add( "kid", getKid( ) ) .add( "alg", getAlg( ) ) .add( "use", getUse( ) ) .add( "keyOps", getKeyOps( ) ) .add( "x5cSize", getX5c( ).map( Collection::size ) ) .toString( ); } static String alg( final JsonNode node ) throws IOException { return Json.text( node, "alg" ); } static Option<List<String>> keyOps( final JsonNode node ) throws IOException { return Json.textListOption( node, "key_ops" ); } static Option<List<String>> x5c( final JsonNode node ) throws IOException { return Json.textListOption( node, "x5c" ); } static Option<String> kid( final JsonNode node ) throws IOException { return Json.textOption( node, "kid" ); } static String kty( final JsonNode node ) throws IOException { return Json.text( node, "kty" ); } static Option<String> use( final JsonNode node ) throws IOException { return Json.textOption( node, "use" ); } static void assertKty( final JsonNode node, final String type ) throws IOException { if ( !type.equals( kty( node ) ) ) { throw new IOException( "Unexpected kty: " + type ); } } protected static String type( Class<? extends JsonWebKey> type ) { return Strings.trimSuffix( JsonWebKey.class.getSimpleName( ), type.getSimpleName( ) ).toUpperCase( ); } }