Package org.jclouds.fujitsu.fgcp.suppliers

Source Code of org.jclouds.fujitsu.fgcp.suppliers.FGCPCredentialsSupplier$FGCPCredentialsForCredentials

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.jclouds.fujitsu.fgcp.suppliers;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collection;

import javax.inject.Inject;

import org.jclouds.crypto.Pems;
import org.jclouds.domain.Credentials;
import org.jclouds.fujitsu.fgcp.FGCPCredentials;
import org.jclouds.io.Payloads;
import org.jclouds.location.Provider;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.io.CharStreams;
import com.google.common.io.LineProcessor;
import com.google.common.util.concurrent.UncheckedExecutionException;

/**
* Loads {@link FGCPCredentials} from a pem file containing certificate and
* private key.
*
* @author Dies Koper
*/
public class FGCPCredentialsSupplier implements Supplier<FGCPCredentials> {
   private final Supplier<Credentials> creds;
   private final LoadingCache<Credentials, FGCPCredentials> keyCache;

   @Inject
   public FGCPCredentialsSupplier(@Provider Supplier<Credentials> creds, FGCPCredentialsForCredentials loader) {
      this.creds = creds;
      // throw out the private key related to old credentials
      this.keyCache = CacheBuilder.newBuilder().maximumSize(2).build(checkNotNull(loader, "loader"));
   }

   /**
    * It is relatively expensive to extract a certificate with private key from
    * a PEM. Cache the relationship between current credentials so that they are
    * only recalculated once.
    */
   @VisibleForTesting
   public static class FGCPCredentialsForCredentials extends CacheLoader<Credentials, FGCPCredentials> {
      @Override
      public FGCPCredentials load(Credentials in) {
         try {
            String identity = in.identity;
            String pem = in.credential;

            // extract private key
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(Pems.privateKeySpec(Payloads.newStringPayload(pem)));

            // extract certificate(s)
            Collection<X509Certificate> certs = x509Certificates(pem);

            return new FGCPCredentials.Builder().identity(identity).credential(pem)
                  .privateKey(privateKey).certificates(certs).build();
         } catch (IOException e) {
            throw Throwables.propagate(e);
         } catch (GeneralSecurityException e) {
            throw new IllegalArgumentException("security exception parsing pem. " + e.getMessage(), e);
         } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("not a valid pem: cannot parse pk. " + e.getMessage(), e);
         }
      }

      /**
       * Returns the collection of X509Certificates that are pem encoded in the
       * input string.<br>
       * Other elements except for pem encoded certificates, e.g. private keys
       * and metadata such as bag attributes are ignored in the pem are ignored.
       *
       * @param pem
       *           encoded certificate(s)
       * @return collection of certificates
       * @throws IOException
       *            in an I/O error occurs
       * @throws CertificateException
       *            on parsing errors
       */
      @SuppressWarnings("unchecked")
      public static Collection<X509Certificate> x509Certificates(String pem) throws IOException, CertificateException {
         // in : pem with Bagattributes metadata and pk
         // out: pem with only certs
         LineProcessor<String> callback = new LineProcessor<String>() {
            static final String CERTIFICATE_X509_END_MARKER = "-----END CERTIFICATE-----";
            StringBuilder result = new StringBuilder();
            boolean insideCert = false;

            public boolean processLine(String line) {
               if (line.startsWith(Pems.CERTIFICATE_X509_MARKER)) {
                  insideCert = true;
               }
               if (insideCert) {
                  result.append(line).append('\n');
               }
               if (line.startsWith(CERTIFICATE_X509_END_MARKER)) {
                  insideCert = false;
               }
               return true; // keep going
            }

            public String getResult() {
               return result.toString();
            }
         };
         String filteredPem = CharStreams.readLines(CharStreams.newReaderSupplier(pem), callback);
         CertificateFactory fact = CertificateFactory.getInstance("X.509");
         return (Collection<X509Certificate>) fact.generateCertificates(new ByteArrayInputStream(filteredPem
               .getBytes(Charsets.UTF_8)));
      }
   }

   @Override
   public FGCPCredentials get() {
      try {
         return keyCache.getUnchecked(checkNotNull(creds.get(), "credential supplier returned null"));
      } catch (UncheckedExecutionException e) {
         throw Throwables.propagate(e.getCause());
      }
   }

}
TOP

Related Classes of org.jclouds.fujitsu.fgcp.suppliers.FGCPCredentialsSupplier$FGCPCredentialsForCredentials

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.