Example #1
0
  /**
   * Delete a public key and related certificates.
   *
   * @param keyName The key name.
   */
  public void deletePublicKeyInfo(Name keyName) throws SecurityException {
    if (keyName.size() == 0) return;

    String keyId = keyName.get(-1).toEscapedString();
    Name identityName = keyName.getPrefix(-1);

    try {
      PreparedStatement statement =
          database_.prepareStatement("DELETE FROM Certificate WHERE " + WHERE_deletePublicKeyInfo);
      statement.setString(1, identityName.toUri());
      statement.setString(2, keyId);

      try {
        statement.executeUpdate();
      } finally {
        statement.close();
      }

      statement = database_.prepareStatement("DELETE FROM Key WHERE " + WHERE_deletePublicKeyInfo);
      statement.setString(1, identityName.toUri());
      statement.setString(2, keyId);

      try {
        statement.executeUpdate();
      } finally {
        statement.close();
      }
    } catch (SQLException exception) {
      throw new SecurityException("BasicIdentityStorage: SQLite error: " + exception);
    }
  }
Example #2
0
  /**
   * Add a public key to the identity storage. Also call addIdentity to ensure that the identityName
   * for the key exists.
   *
   * @param keyName The name of the public key to be added.
   * @param keyType Type of the public key to be added.
   * @param publicKeyDer A blob of the public key DER to be added.
   * @throws SecurityException if a key with the keyName already exists.
   */
  public final void addKey(Name keyName, KeyType keyType, Blob publicKeyDer)
      throws SecurityException {
    if (keyName.size() == 0) return;

    checkAddKey(keyName);

    String keyId = keyName.get(-1).toEscapedString();
    Name identityName = keyName.getPrefix(-1);

    addIdentity(identityName);

    try {
      PreparedStatement statement =
          database_.prepareStatement(
              "INSERT INTO Key (identity_name, key_identifier, key_type, public_key) values (?, ?, ?, ?)");
      statement.setString(1, identityName.toUri());
      statement.setString(2, keyId);
      statement.setInt(3, keyType.getNumericType());
      statement.setBytes(4, publicKeyDer.getImmutableArray());

      try {
        statement.executeUpdate();
      } finally {
        statement.close();
      }
    } catch (SQLException exception) {
      throw new SecurityException("BasicIdentityStorage: SQLite error: " + exception);
    }
  }
Example #3
0
  /**
   * Set a key as the default key of an identity. The identity name is inferred from keyName.
   *
   * @param keyName The name of the key.
   * @param identityNameCheck The identity name to check that the keyName contains the same identity
   *     name. If an empty name, it is ignored.
   */
  public final void setDefaultKeyNameForIdentity(Name keyName, Name identityNameCheck)
      throws SecurityException {
    checkSetDefaultKeyNameForIdentity(keyName, identityNameCheck);

    String keyId = keyName.get(-1).toEscapedString();
    Name identityName = keyName.getPrefix(-1);

    try {
      // Reset the previous default Key.
      PreparedStatement statement =
          database_.prepareStatement(
              "UPDATE Key SET default_key=0 WHERE " + WHERE_setDefaultKeyNameForIdentity_reset);
      statement.setString(1, identityName.toUri());
      try {
        statement.executeUpdate();
      } finally {
        statement.close();
      }

      // Set the current default Key.
      statement =
          database_.prepareStatement(
              "UPDATE Key SET default_key=1 WHERE " + WHERE_setDefaultKeyNameForIdentity_set);
      statement.setString(1, identityName.toUri());
      statement.setString(2, keyId);
      try {
        statement.executeUpdate();
      } finally {
        statement.close();
      }
    } catch (SQLException exception) {
      throw new SecurityException("BasicIdentityStorage: SQLite error: " + exception);
    }
  }
Example #4
0
  /**
   * Return a new Signature object based on the signature algorithm of the public key with keyName
   * (derived from certificateName).
   *
   * @param certificateName The certificate name.
   * @param digestAlgorithm Set digestAlgorithm[0] to the signature algorithm's digest algorithm,
   *     e.g. DigestAlgorithm.SHA256.
   * @return A new object of the correct subclass of Signature.
   */
  private Signature makeSignatureByCertificate(
      Name certificateName, DigestAlgorithm[] digestAlgorithm) throws SecurityException {
    Name keyName = IdentityCertificate.certificateNameToPublicKeyName(certificateName);
    PublicKey publicKey = privateKeyStorage_.getPublicKey(keyName);
    KeyType keyType = publicKey.getKeyType();

    if (keyType == KeyType.RSA) {
      Sha256WithRsaSignature signature = new Sha256WithRsaSignature();
      digestAlgorithm[0] = DigestAlgorithm.SHA256;

      signature.getKeyLocator().setType(KeyLocatorType.KEYNAME);
      signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1));

      return signature;
    } else if (keyType == KeyType.ECDSA) {
      Sha256WithEcdsaSignature signature = new Sha256WithEcdsaSignature();
      digestAlgorithm[0] = DigestAlgorithm.SHA256;

      signature.getKeyLocator().setType(KeyLocatorType.KEYNAME);
      signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1));

      return signature;
    } else throw new SecurityException("Key type is not recognized");
  }
Example #5
0
  /**
   * Generate a self-signed certificate for a public key.
   *
   * @param keyName The name of the public key.
   * @return The generated certificate.
   */
  public IdentityCertificate selfSign(Name keyName) throws SecurityException {
    IdentityCertificate certificate = new IdentityCertificate();

    Blob keyBlob = identityStorage_.getKey(keyName);
    PublicKey publicKey = new PublicKey(keyBlob);

    Calendar calendar = Calendar.getInstance();
    double notBefore = (double) calendar.getTimeInMillis();
    calendar.add(Calendar.YEAR, 2);
    double notAfter = (double) calendar.getTimeInMillis();

    certificate.setNotBefore(notBefore);
    certificate.setNotAfter(notAfter);

    Name certificateName =
        keyName
            .getPrefix(-1)
            .append("KEY")
            .append(keyName.get(-1))
            .append("ID-CERT")
            .appendVersion((long) certificate.getNotBefore());
    certificate.setName(certificateName);

    certificate.setPublicKeyInfo(publicKey);
    certificate.addSubjectDescription(
        new CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
    try {
      certificate.encode();
    } catch (DerEncodingException ex) {
      // We don't expect this to happen.
      Logger.getLogger(IdentityManager.class.getName()).log(Level.SEVERE, null, ex);
      return null;
    } catch (DerDecodingException ex) {
      // We don't expect this to happen.
      Logger.getLogger(IdentityManager.class.getName()).log(Level.SEVERE, null, ex);
      return null;
    }

    signByCertificate(certificate, certificate.getName());

    return certificate;
  }
Example #6
0
  /**
   * In table Key, set 'active' to isActive for the keyName.
   *
   * @param keyName The name of the key.
   * @param isActive The value for the 'active' field.
   */
  protected void updateKeyStatus(Name keyName, boolean isActive) throws SecurityException {
    String keyId = keyName.get(-1).toEscapedString();
    Name identityName = keyName.getPrefix(-1);

    try {
      PreparedStatement statement =
          database_.prepareStatement("UPDATE Key SET active=? WHERE " + WHERE_updateKeyStatus);
      statement.setInt(1, (isActive ? 1 : 0));
      statement.setString(2, identityName.toUri());
      statement.setString(3, keyId);

      try {
        statement.executeUpdate();
      } finally {
        statement.close();
      }
    } catch (SQLException exception) {
      throw new SecurityException("BasicIdentityStorage: SQLite error: " + exception);
    }
  }
Example #7
0
  /**
   * Check if the specified key already exists.
   *
   * @param keyName The name of the key.
   * @return true if the key exists, otherwise false.
   */
  public final boolean doesKeyExist(Name keyName) throws SecurityException {
    String keyId = keyName.get(-1).toEscapedString();
    Name identityName = keyName.getPrefix(-1);

    try {
      PreparedStatement statement = database_.prepareStatement(SELECT_doesKeyExist);
      statement.setString(1, identityName.toUri());
      statement.setString(2, keyId);

      try {
        ResultSet result = statement.executeQuery();

        if (result.next()) return result.getInt(1) > 0;
        else return false;
      } finally {
        statement.close();
      }
    } catch (SQLException exception) {
      throw new SecurityException("BasicIdentityStorage: SQLite error: " + exception);
    }
  }
Example #8
0
  /**
   * Add a certificate to the identity storage.
   *
   * @param certificate The certificate to be added. This makes a copy of the certificate.
   * @throws SecurityException if the certificate is already installed.
   */
  public final void addCertificate(IdentityCertificate certificate) throws SecurityException {
    checkAddCertificate(certificate);

    Name certificateName = certificate.getName();
    Name keyName = certificate.getPublicKeyName();

    // Insert the certificate.
    try {
      PreparedStatement statement =
          database_.prepareStatement(
              "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data) "
                  + "values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)");
      statement.setString(1, certificateName.toUri());

      Name signerName = KeyLocator.getFromSignature(certificate.getSignature()).getKeyName();
      statement.setString(2, signerName.toUri());

      String keyId = keyName.get(-1).toEscapedString();
      Name identity = keyName.getPrefix(-1);
      statement.setString(3, identity.toUri());
      statement.setString(4, keyId);

      // Convert from milliseconds to seconds since 1/1/1970.
      statement.setLong(5, (long) (Math.floor(certificate.getNotBefore() / 1000.0)));
      statement.setLong(6, (long) (Math.floor(certificate.getNotAfter() / 1000.0)));

      // wireEncode returns the cached encoding if available.
      statement.setBytes(7, certificate.wireEncode().getImmutableArray());

      try {
        statement.executeUpdate();
      } finally {
        statement.close();
      }
    } catch (SQLException exception) {
      throw new SecurityException("BasicIdentityStorage: SQLite error: " + exception);
    }
  }
Example #9
0
  /**
   * Get the public key DER blob from the identity storage.
   *
   * @param keyName The name of the requested public key.
   * @return The DER Blob. If not found, return a Blob with a null pointer.
   */
  public final Blob getKey(Name keyName) throws SecurityException {
    if (!doesKeyExist(keyName)) return new Blob();

    String keyId = keyName.get(-1).toEscapedString();
    Name identityName = keyName.getPrefix(-1);

    try {
      PreparedStatement statement = database_.prepareStatement(SELECT_getKey);
      statement.setString(1, identityName.toUri());
      statement.setString(2, keyId);

      try {
        ResultSet result = statement.executeQuery();

        if (result.next()) return new Blob(result.getBytes("public_key"));
        else return new Blob();
      } finally {
        statement.close();
      }
    } catch (SQLException exception) {
      throw new SecurityException("BasicIdentityStorage: SQLite error: " + exception);
    }
  }
Example #10
0
  /**
   * Get the default certificate name for the specified key.
   *
   * @param keyName The key name.
   * @return The default certificate name.
   * @throws SecurityException if the default certificate name for the key name is not set.
   */
  public final Name getDefaultCertificateNameForKey(Name keyName) throws SecurityException {
    String keyId = keyName.get(-1).toEscapedString();
    Name identityName = keyName.getPrefix(-1);

    try {
      PreparedStatement statement =
          database_.prepareStatement(SELECT_getDefaultCertificateNameForKey);
      statement.setString(1, identityName.toUri());
      statement.setString(2, keyId);

      try {
        ResultSet result = statement.executeQuery();

        if (result.next()) return new Name(result.getString("cert_name"));
        else
          throw new SecurityException(
              "BasicIdentityStorage.getDefaultCertificateNameForKey: The default certificate for the key name is not defined");
      } finally {
        statement.close();
      }
    } catch (SQLException exception) {
      throw new SecurityException("BasicIdentityStorage: SQLite error: " + exception);
    }
  }
Example #11
0
  /**
   * Prepare an unsigned identity certificate.
   *
   * @param keyName The key name, e.g., `/{identity_name}/ksk-123456`.
   * @param publicKey The public key to sign.
   * @param signingIdentity The signing identity.
   * @param notBefore See IdentityCertificate.
   * @param notAfter See IdentityCertificate.
   * @param subjectDescription A list of CertificateSubjectDescription. See IdentityCertificate. If
   *     null or empty, this adds a an ATTRIBUTE_NAME based on the keyName.
   * @param certPrefix The prefix before the `KEY` component. If null, this infers the certificate
   *     name according to the relation between the signingIdentity and the subject identity. If the
   *     signingIdentity is a prefix of the subject identity, `KEY` will be inserted after the
   *     signingIdentity, otherwise `KEY` is inserted after subject identity (i.e., before
   *     `ksk-...`).
   * @return The unsigned IdentityCertificate, or null if the inputs are invalid.
   */
  public final IdentityCertificate prepareUnsignedIdentityCertificate(
      Name keyName,
      PublicKey publicKey,
      Name signingIdentity,
      double notBefore,
      double notAfter,
      List subjectDescription,
      Name certPrefix)
      throws SecurityException {
    if (keyName.size() < 1) return null;

    String tempKeyIdPrefix = keyName.get(-1).toEscapedString();
    if (tempKeyIdPrefix.length() < 4) return null;
    String keyIdPrefix = tempKeyIdPrefix.substring(0, 4);
    if (!keyIdPrefix.equals("ksk-") && !keyIdPrefix.equals("dsk-")) return null;

    IdentityCertificate certificate = new IdentityCertificate();
    Name certName = new Name();

    if (certPrefix == null) {
      // No certificate prefix hint, so infer the prefix.
      if (signingIdentity.match(keyName))
        certName
            .append(signingIdentity)
            .append("KEY")
            .append(keyName.getSubName(signingIdentity.size()))
            .append("ID-CERT")
            .appendVersion((long) Common.getNowMilliseconds());
      else
        certName
            .append(keyName.getPrefix(-1))
            .append("KEY")
            .append(keyName.get(-1))
            .append("ID-CERT")
            .appendVersion((long) Common.getNowMilliseconds());
    } else {
      // A cert prefix hint is supplied, so determine the cert name.
      if (certPrefix.match(keyName) && !certPrefix.equals(keyName))
        certName
            .append(certPrefix)
            .append("KEY")
            .append(keyName.getSubName(certPrefix.size()))
            .append("ID-CERT")
            .appendVersion((long) Common.getNowMilliseconds());
      else return null;
    }

    certificate.setName(certName);
    certificate.setNotBefore(notBefore);
    certificate.setNotAfter(notAfter);
    certificate.setPublicKeyInfo(publicKey);

    if (subjectDescription == null || subjectDescription.isEmpty())
      certificate.addSubjectDescription(
          new CertificateSubjectDescription("2.5.4.41", keyName.getPrefix(-1).toUri()));
    else {
      for (int i = 0; i < subjectDescription.size(); ++i)
        certificate.addSubjectDescription(
            (CertificateSubjectDescription) subjectDescription.get(i));
    }

    try {
      certificate.encode();
    } catch (DerEncodingException ex) {
      throw new SecurityException("DerEncodingException: " + ex);
    } catch (DerDecodingException ex) {
      throw new SecurityException("DerDecodingException: " + ex);
    }

    return certificate;
  }