/* * Copyright (C) 2014 Intel Corporation * All rights reserved. */ package com.intel.mtwilson.tls.policy.creator.impl; import com.intel.dcsg.cpg.codec.ByteArrayCodec; import com.intel.dcsg.cpg.crypto.CryptographyException; import com.intel.dcsg.cpg.tls.policy.impl.PublicKeyTlsPolicy; import com.intel.dcsg.cpg.x509.repository.HashSetMutablePublicKeyRepository; import com.intel.dcsg.cpg.x509.repository.PublicKeyRepository; import com.intel.mtwilson.tls.policy.TlsPolicyDescriptor; import com.intel.dcsg.cpg.crypto.PublicKeyCodec; import com.intel.mtwilson.tls.policy.factory.TlsPolicyCreator; import java.security.PublicKey; import com.intel.mtwilson.tls.policy.factory.TlsPolicyFactoryUtil; /** * * @author jbuhacoff */ public class PublicKeyTlsPolicyCreator implements TlsPolicyCreator { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PublicKeyTlsPolicyCreator.class); private PublicKeyCodec publicKeyCodec = new PublicKeyCodec(); @Override public PublicKeyTlsPolicy createTlsPolicy(TlsPolicyDescriptor tlsPolicyDescriptor) { if( "public-key".equalsIgnoreCase(tlsPolicyDescriptor.getPolicyType()) ) { try { PublicKeyRepository repository = getPublicKeyRepository(tlsPolicyDescriptor); return new PublicKeyTlsPolicy(repository); //return TlsPolicyBuilder.factory().strict(repository).skipHostnameVerification().build(); } catch(CryptographyException e) { throw new IllegalArgumentException("Cannot create public key policy from given repository", e); } } return null; } protected PublicKeyRepository getPublicKeyRepository(TlsPolicyDescriptor tlsPolicyDescriptor) throws CryptographyException { if( "public-key".equals(tlsPolicyDescriptor.getPolicyType()) && tlsPolicyDescriptor.getData() != null ) { if( tlsPolicyDescriptor.getData() == null || tlsPolicyDescriptor.getData().isEmpty() ) { throw new IllegalArgumentException("TLS policy descriptor does not contain any public keys"); } ByteArrayCodec codec = getCodecForTlsPolicyDescriptor(tlsPolicyDescriptor); if( codec == null ) { throw new IllegalArgumentException("TlsPolicyDescriptor indicates public keys but does not declare public key encoding"); } HashSetMutablePublicKeyRepository repository = new HashSetMutablePublicKeyRepository(); for(String publicKeyEncoded : tlsPolicyDescriptor.getData()) { PublicKey publicKey = publicKeyCodec.decode(codec.decode(publicKeyEncoded)); repository.addPublicKey(publicKey); } return repository; } return null; } protected ByteArrayCodec getCodecForTlsPolicyDescriptor(TlsPolicyDescriptor tlsPolicyDescriptor) { ByteArrayCodec codec; PublicKeyMetadata meta = getPublicKeyMetadata(tlsPolicyDescriptor); if( meta.encoding == null ) { // attempt auto-detection based on first certificate String sample = TlsPolicyFactoryUtil.getFirst(tlsPolicyDescriptor.getData()); meta.encoding = TlsPolicyFactoryUtil.guessEncodingForData(sample); // safe because if input is null return value will be null log.debug("Guessing codec {} for sample data {}", meta.encoding, sample); } codec = TlsPolicyFactoryUtil.getCodecByName(meta.encoding); // safe because if input is null return value will be null log.debug("Codec {} for cerrtificate encoding {}", (codec==null?"null":codec.getClass().getName()), meta.encoding); return codec; } public static class PublicKeyMetadata { public String encoding; // base64 } /** * * @param tlsPolicyDescriptor * @return an instance of CertificateDigestMetadata, but some fields may be null if they were not included in the descriptor's meta section */ public static PublicKeyMetadata getPublicKeyMetadata(TlsPolicyDescriptor tlsPolicyDescriptor) { PublicKeyMetadata metadata = new PublicKeyMetadata(); if( tlsPolicyDescriptor.getMeta() == null ) { return metadata; } if(tlsPolicyDescriptor.getMeta() == null) { throw new IllegalArgumentException("TLS policy descriptor metadata cannot be null."); } if( tlsPolicyDescriptor.getMeta().get("encoding") != null && !tlsPolicyDescriptor.getMeta().get("encoding").isEmpty() ) { metadata.encoding = tlsPolicyDescriptor.getMeta().get("encoding"); } return metadata; } }