Package com.google.k2crypto

Source Code of com.google.k2crypto.Key

/*
* Copyright 2014 Google Inc. All rights reserved.
*
* 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 com.google.k2crypto;

import com.google.k2crypto.KeyProto.KeyCore;
import com.google.k2crypto.KeyProto.KeyData;
import com.google.k2crypto.exceptions.BuilderException;
import com.google.k2crypto.exceptions.InvalidKeyDataException;
import com.google.k2crypto.exceptions.KeyModifierException;
import com.google.k2crypto.exceptions.UnregisteredKeyVersionException;
import com.google.k2crypto.keyversions.KeyVersion;
import com.google.k2crypto.keyversions.KeyVersionProto.KeyVersionData;
import com.google.k2crypto.keyversions.KeyVersionRegistry;
import com.google.protobuf.ByteString;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.InvalidProtocolBufferException;

import java.util.ArrayList;
import java.util.List;

/**
* This class represents a Key in K2. It holds a list of KeyVersions and a
* reference to the primary KeyVersion.
*
* @author John Maheswaran (maheswaran@google.com)
*/
public class Key {
 
  // Retained raw bytes of the core key information
  // (Cannot be changed once generated)
  private ByteString coreBytes = null;

  /**
   * The list of key versions
   */
  private ArrayList<KeyVersion> keyVersions = new ArrayList<KeyVersion>();

  /**
   *
   */
  private KeyVersion primary;

  /**
   * Empty constructor - construct an empty Key
   */
  public Key() {}

  /**
   * Construct a Key with a single KeyVersion
   *
   * @param kv A KeyVersion to initialize the Key with
   */
  public Key(KeyVersion kv) {
    // Add the key version to the key
    this.keyVersions.add(kv);
    // set the primary to the key version (the only key version in the key)
    this.primary = kv;
  }

  /**
   * Construct a Key from protobuf data.
   *
   * @param context Context of the K2 session.
   * @param data Protobuf data of the key.
   *
   * @throws UnregisteredKeyVersionException if the data contains a key version
   *     type that has no registered implementation.
   * @throws InvalidKeyDataException if the protobuf data is invalid.
   */
  public Key(K2Context context, KeyData data)
      throws UnregisteredKeyVersionException, InvalidKeyDataException {
   
    // NOTE: lower-level exceptions take precedence by design
   
    KeyVersionRegistry registry = context.getKeyVersionRegistry();
    ExtensionRegistry protoRegistry = registry.getProtoExtensions();

    // Retain the core
    if (!data.hasCore()) {
      // Core field is required
      throw new InvalidKeyDataException(
          InvalidKeyDataException.Reason.PROTO_PARSE, null);
    }
    coreBytes = data.getCore();
   
    // Parse the core, containing the security/usage constraints
    KeyCore core;
    try {
      core = KeyCore.parseFrom(coreBytes, protoRegistry);
    } catch (InvalidProtocolBufferException ex) {
      throw new InvalidKeyDataException(
          InvalidKeyDataException.Reason.PROTO_PARSE, ex);
    }
    // TODO(darylseah): extract security properties from core

    // Extract the key version list
    final int kvCount = data.getKeyVersionCount();
    keyVersions.ensureCapacity(kvCount);

    UnregisteredKeyVersionException unregisteredException = null;
    InvalidKeyDataException buildException = null;
   
    for (KeyVersionData kvData : data.getKeyVersionList()) {
      if (!kvData.hasType()) {
        // Type field is required
        throw new InvalidKeyDataException(
            InvalidKeyDataException.Reason.PROTO_PARSE, null);
      }
      try {
        KeyVersion kv = registry.newBuilder(kvData.getType())
            .withData(kvData, protoRegistry).build();
        keyVersions.add(kv);
      } catch (InvalidProtocolBufferException ex) {
        // Throw proto parsing exceptions immediately
        throw new InvalidKeyDataException(
            InvalidKeyDataException.Reason.PROTO_PARSE, ex);
      } catch (RuntimeException ex) {
        // We consider runtime exceptions to be parsing exceptions
        throw new InvalidKeyDataException(
            InvalidKeyDataException.Reason.PROTO_PARSE, ex);       
      } catch (BuilderException ex) {
        // Delay-throw builder exceptions...
        buildException = new InvalidKeyDataException(
            InvalidKeyDataException.Reason.KEY_VERSION_BUILD, ex);
      } catch (UnregisteredKeyVersionException ex) {
        // ...and unregistered key version exceptions
        unregisteredException = ex;
      }
    }

    // Unregistered key versions take precedence over build exceptions
    if (unregisteredException != null) {
      throw unregisteredException;
    } else if (buildException != null) {
      throw buildException;
    }
   
    // Extract the primary
    if (kvCount > 0) {
      int primaryIndex = (data.hasPrimary() ? data.getPrimary() : -1);
      if (primaryIndex < 0 || primaryIndex >= keyVersions.size()) {
        throw new InvalidKeyDataException(
            InvalidKeyDataException.Reason.CORRUPTED_PRIMARY, null);
      }
      primary = keyVersions.get(primaryIndex);     
    }
  }

  /**
   * Returns the raw bytes of the core data of the key.
   * Will invoke {@link #buildCore()} to generate it if needed.
   */
  protected final ByteString getCore() {
    ByteString core = coreBytes;
    if (core == null) {
      core = buildCore().build().toByteString();
      coreBytes = core;
    }
    return core;
  }
 
  /**
   * Returns a builder for building the protobuf core of the key.
   *
   * <p>The core contains all the security properties of the key.
   */
  protected KeyCore.Builder buildCore() {
    KeyCore.Builder builder = KeyCore.newBuilder();
    // TODO(darylseah): populate core with security properties
    return builder;
  }
 
  /**
   * Returns a builder for building the protobuf data of the key.
   *
   * <p>The data contains the core as well as the key versions in the key.
   */
  public KeyData.Builder buildData() {
    KeyData.Builder builder = KeyData.newBuilder();
    builder.setCore(getCore());
    List<KeyVersion> keyVersions = this.keyVersions;
    final int size = keyVersions.size();
    for (int i = 0; i < size; ++i) {
      KeyVersion kv = keyVersions.get(i);
      builder.addKeyVersion(kv.buildData());
      if (kv == primary) {
        builder.setPrimary(i);
      }
    }
    if (size > 0 && !builder.hasPrimary()) {
      throw new AssertionError("Corrupted key state.");
    }
    return builder;
  }
 
  /**
   * Method to add a KeyVersion to this Key
   *
   * @param keyVersion
   */
  protected void addKeyVersion(KeyVersion keyVersion) {
    // TODO: duplicate checking
    this.keyVersions.add(keyVersion);
    // If there is only one keyversion in the key, set it as the primary
    if (this.keyVersions.size() == 1) {
      this.primary = keyVersion;
    }
  }

  /**
   * Method to obtain the primary KeyVersion in this Key
   *
   * @return the primary KeyVersion in this Key
   */
  protected KeyVersion getPrimary() {
    return this.primary;
  }

  /**
   * Method to get the number of key versions in this key
   *
   * @return the number of key versions in this key
   */
  protected int getKeyVersionsCount() {
    return this.keyVersions.size();
  }

  /**
   * Sets a given keyversion as the primary in the key
   *
   * @param keyversion the keyversion to set as the primary
   */
  protected void setPrimary(KeyVersion keyversion) {
    // TODO: check that the primary keyversion is in the list
    this.primary = keyversion;

  }

  /**
   * Removes a given keyversion from the key
   *
   * @param keyversion the keyversion to remove from the key
   * @throws KeyModifierException
   */
  protected void removeKeyVersion(KeyVersion keyversion)
      throws KeyModifierException {
    if (!keyVersions.contains(keyversion)) {
      throw new KeyModifierException(
          "Given KeyVersion is not in the Key");
    } else if (this.primary == keyversion) {
      throw new KeyModifierException(
          "Cannot remove KeyVersion as it is the primary in the Key");
    } else {
      this.keyVersions.remove(keyversion);
    }
  }

  /**
   * Check if the Key contains a given KeyVersion
   *
   * @param keyversion The KeyVersion to check if it is in the Key
   * @return Returns true if and only if keyversion is in this Key
   */
  protected boolean containsKeyVersion(KeyVersion keyversion) {
    return this.keyVersions.contains(keyversion);
  }
}
TOP

Related Classes of com.google.k2crypto.Key

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.