Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions at_client/src/main/java/org/atsign/client/api/AtKeyNames.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.atsign.client.api;

import org.atsign.common.AtSign;

/**
* Constants and Utility methods for "well known" standard keys
*/
public class AtKeyNames {

/**
* Key name for an Atsign's public encryption key
*/
public static final String PUBLIC_ENCRYPT = "publickey";

/**
* Key name used during activation of Atsign server with CRAM authentication
*/
public static final String PRIVATE_AT_SECRET = "privatekey:at_secret";

/**
* Key name used to store a shared encryption key between two {@link AtSign}s
*/
public static final String SHARED_KEY = "shared_key";

/**
* Key name used during enrollment completion, this is used to obtain the self encryption
* for an {@link AtSign}
*/
public static final String SELF_ENCRYPTION_KEY = "default_self_enc_key";

/**
* Key name used during enrollment completion, this is used to obtain the private encryption
* key for an {@link AtSign}
*/
public static final String ENCRYPT_PRIVATE_KEY = "default_enc_private_key";

/**
* Returns the key name used to store the shared encryption key encrypted with
* the sharedBy {@link AtSign}'s public key
*
* @param sharedWith the sharedWith (recipient) {@link AtSign}
* @return the fully qualified key name
*/
public static String toSharedByMeKeyName(AtSign sharedWith) {
return String.format("%s.%s", SHARED_KEY, sharedWith.withoutPrefix());
}


/**
*
* @return the key used to shared
*/
public static String toSharedWithMeKeyName(AtSign sharedBy, AtSign sharedWith) {
return String.format("%s:%s%s", SHARED_KEY, sharedWith, sharedBy);
}

}
183 changes: 69 additions & 114 deletions at_client/src/main/java/org/atsign/client/api/AtKeys.java
Original file line number Diff line number Diff line change
@@ -1,196 +1,151 @@
package org.atsign.client.api;

import java.security.Key;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.atsign.client.util.EnrollmentId;

import lombok.Builder;
import lombok.Value;

/**
* Data class used to hold an {@link org.atsign.client.api.AtClient}s keys
* An immutable class used to hold an {@link org.atsign.client.api.AtClient}s keys.
* <p>
* Examples:
*
* <pre>
* AtKeys keys = AtKeys.builder()
* .selfEncryptKey(generateAESKeyBase64())
* .apkamKeyPair(generateRSAKeyPair())
* .apkamSymmetricKey(generateAESKeyBase64())
* .build();
*
* keys = keys.toBuilder().enrollmentId(enrollmentId).build();
* </pre>
*/
@Value
@Builder(toBuilder = true)
public class AtKeys {

/**
* unique id which is assigned by the at_server at enrollment time, this is associated with a
* specific
* application and device and therefore a specific the apkam key pair
* specific application and device and therefore a specific the apkam key pair
*/
private EnrollmentId enrollmentId;
EnrollmentId enrollmentId;

/**
* Public Key used for Authentication Management, once this is stored in the at_server then an
* {@link org.atsign.client.api.AtClient} is able to authenticate using the corresponding private
* key.
*/
private String apkamPublicKey;
String apkamPublicKey;

/**
* Private Key used for Authentication Management, this is used to sign the challenge during
* authentication with the at_server.
*/
private String apkamPrivateKey;
String apkamPrivateKey;

/**
* Encryption Key used during enrollment. This key is sent as part of the enrollment request
* (encrypted
* with the atsigns public encryption key). The process that approves the enrollment request uses
* this
* key to encrypt the {@link #selfEncryptKey} and {@link #encryptPrivateKey} in the response that it
* sends.
* (encrypted with the atsigns public encryption key). The process that approves the enrollment
* request uses this key to encrypt the {@link #selfEncryptKey} and {@link #encryptPrivateKey}
* in the response that it sends.
* The process which requested the enrollment can then decrypt and store those keys.
* This ensures that all {@link AtKeys} got and {@link org.atsign.common.AtSign} share the same
* {@link #selfEncryptKey} and {@link #encryptPrivateKey}
*/
private String apkamSymmetricKey;
String apkamSymmetricKey;

/**
* Encryption Key used to encrypt {@link org.atsign.common.Keys.SelfKey}s and the pkam and
* encryption key pairs
* when they are externalised as JSON
*/
private String selfEncryptKey;
String selfEncryptKey;

/**
* This is used to encrypt the symmetric keys that are used to encrypt
* {@link org.atsign.common.Keys.SharedKey}s
* where the shared with {@link org.atsign.common.AtSign} is this {@link org.atsign.common.AtSign}
*/

private String encryptPublicKey;
String encryptPublicKey;

/**
* This is used to decrypt the symmetric keys that are used to encrypt
* {@link org.atsign.common.Keys.SharedKey}s
* where the shared with {@link org.atsign.common.AtSign} is this {@link org.atsign.common.AtSign}
*/
private String encryptPrivateKey;
String encryptPrivateKey;

/**
* Transient cache of other keys
*/
private Map<String, String> cache = new ConcurrentHashMap<>();
Map<String, String> cache = new ConcurrentHashMap<>();

/**
* @return true if these {link @AtKeys} have enrollment id
*/
public boolean hasEnrollmentId() {
return enrollmentId != null;
}

public EnrollmentId getEnrollmentId() {
return enrollmentId;
}

public AtKeys setEnrollmentId(EnrollmentId enrollmentId) {
this.enrollmentId = enrollmentId;
return this;
}

public String getSelfEncryptKey() {
return selfEncryptKey;
}

public AtKeys setSelfEncryptKey(String key) {
this.selfEncryptKey = key;
return this;
}

public String getApkamPublicKey() {
return apkamPublicKey;
}

public AtKeys setApkamPublicKey(String key) {
this.apkamPublicKey = key;
return this;
}

public AtKeys setApkamPublicKey(PublicKey key) {
return setApkamPublicKey(createStringBase64(key));
}

public String getApkamPrivateKey() {
return apkamPrivateKey;
}

public AtKeys setApkamPrivateKey(String key) {
this.apkamPrivateKey = key;
return this;
}

public AtKeys setApkamPrivateKey(PrivateKey key) {
return setApkamPrivateKey(createStringBase64(key));
}

public AtKeys setApkamKeyPair(KeyPair keyPair) {
setApkamPublicKey(keyPair.getPublic());
setApkamPrivateKey(keyPair.getPrivate());
return this;
}

public boolean hasPkamKeys() {
return this.apkamPublicKey != null && this.apkamPrivateKey != null;
}

public AtKeys setEncryptKeyPair(KeyPair keyPair) {
setEncryptPublicKey(keyPair.getPublic());
setEncryptPrivateKey(keyPair.getPrivate());
return this;
}

public String getEncryptPublicKey() {
return encryptPublicKey;
}

public AtKeys setEncryptPublicKey(String key) {
this.encryptPublicKey = key;
return this;
}

public AtKeys setEncryptPublicKey(PublicKey key) {
return setEncryptPublicKey(createStringBase64(key));
}

public String getEncryptPrivateKey() {
return encryptPrivateKey;
}

public AtKeys setEncryptPrivateKey(String key) {
this.encryptPrivateKey = key;
return this;
}

public AtKeys setEncryptPrivateKey(PrivateKey key) {
return setEncryptPrivateKey(createStringBase64(key));
}

public String getApkamSymmetricKey() {
return apkamSymmetricKey;
}

public AtKeys setApkamSymmetricKey(String key) {
this.apkamSymmetricKey = key;
return this;
/**
* @return true if these {link @AtKeys} have APKAM private key set
*/
public boolean hasPkamKey() {
return this.apkamPrivateKey != null;
}

/**
* Allows the retrieval of previously put key values from the transient cache.
*
* @param key for the cached value
* @return cached value or null if no entry
*/
public String get(String key) {
return cache.get(key);
}

/**
* Allows the storage key values in the transient cache.
*
* @param key for the cached value
* @param value the cached value
*/
public void put(String key, String value) {
cache.put(key, value);
}

/**
* @return an immutable map of all the transient cached values
*/
public Map<String, String> getCache() {
return Collections.unmodifiableMap(cache);
}

private static String createStringBase64(PublicKey key) {
return Base64.getEncoder().encodeToString(key.getEncoded());
/**
* Builder utility.
*/
public static class AtKeysBuilder {

public AtKeysBuilder encryptKeyPair(KeyPair keyPair) {
return this.encryptPublicKey(createStringBase64(keyPair.getPublic()))
.encryptPrivateKey(createStringBase64(keyPair.getPrivate()));
}

public AtKeysBuilder apkamKeyPair(KeyPair keyPair) {
return this.apkamPublicKey(createStringBase64(keyPair.getPublic()))
.apkamPrivateKey(createStringBase64(keyPair.getPrivate()));
}
}

private static String createStringBase64(PrivateKey key) {
private static String createStringBase64(Key key) {
return Base64.getEncoder().encodeToString(key.getEncoded());
}

Expand Down
Loading
Loading