Skip to content

Commit

Permalink
Introduce common IKey interface (#564)
Browse files Browse the repository at this point in the history
Currently JavaThemis deals only with asymmetric keys and thus has
an "AsymmetricKey" class providing common implementation of storage and
utilities for PrivateKey and PublicKey classes. However, we are going to
introduce a new type of keys -- "SymmetricKey" -- which will need these
utilities as well. Since it's not an AsymmetricKey, let's refactor our
class hierarchy a bit.

Extract declaration of the "toByteArray()" utility method into a new
interface "IKey". This interface will be implemented by all key classes
of Themis and will provide common utilities. (E.g., base64 formatting
may be added here in the future.)

Extract storage implementation into a new "KeyBytes" class. It is an
abstract package-private class, intended to be a base class for all
keys implemented by Themis. It provides "key" field to access key bytes
directly and implements IKey interface. It also maintains the invariant
that all valid keys must be non-null and not empty.

KeyBytes keeps a copy of the original byte[] array and copies it again
in toByteArray() implementation. This is because Java arrays are always
mutable that we have to copy them in order to be sure that the user can
never modify the data stored in KeyBytes.

AsymmetricKey is left as a marker abstract class. It inherits storage
and IKey implementation from KeyBytes. Plus, it still hosts the
constants for asymmetric key types.
  • Loading branch information
ilammy committed Dec 11, 2019
1 parent e1196ea commit 8fe48f5
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ _Code:_
- JNI libraries are now available as `libthemis-jni` packages for supported Linux systems ([#552](https://github.com/cossacklabs/themis/pull/552), [#553](https://github.com/cossacklabs/themis/pull/553)).
- Fixed a NullPointerException bug in `SecureSocket` initialisation ([#557](https://github.com/cossacklabs/themis/pull/557)).
- Some Themis exceptions have been converted from checked `Exception` to _unchecked_ `RuntimeException`, relaxing requirements for `throws` specifiers ([#563](https://github.com/cossacklabs/themis/pull/563)).
- Introduced `IKey` interface with accessors to raw key data ([#564](https://github.com/cossacklabs/themis/pull/564)).

- **Node.js**

Expand Down
24 changes: 9 additions & 15 deletions src/wrappers/themis/java/com/cossacklabs/themis/AsymmetricKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,20 @@
/**
* Base class for Themis asymmetric keys
*/
public abstract class AsymmetricKey {
public abstract class AsymmetricKey extends KeyBytes {

public static final int KEYTYPE_EC = 0;
public static final int KEYTYPE_RSA = 1;

byte[] key;

/**
* Creates asymmetric key from byte array
* @param [in] key
* Creates asymmetric key from byte array.
*
* @param key byte array
*
* @throws NullArgumentException if `key` is null.
* @throws InvalidArgumentException if `key` is empty.
*/
public AsymmetricKey(byte[] key) {
this.key = key;
}

/**
* Serializes this key to a byte array
* @return key as byte array
*/
public byte[] toByteArray() {
return key.clone();
super(key);
}
}
30 changes: 30 additions & 0 deletions src/wrappers/themis/java/com/cossacklabs/themis/IKey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2019 Cossack Labs Limited
*
* 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.cossacklabs.themis;

/**
* Cryptographic key.
*/
public interface IKey {

/**
* Serializes this key to a byte array.
*
* @return key as byte array.
*/
public byte[] toByteArray();
}
52 changes: 52 additions & 0 deletions src/wrappers/themis/java/com/cossacklabs/themis/KeyBytes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2019 Cossack Labs Limited
*
* 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.cossacklabs.themis;

/**
* Key byte storage.
*/
abstract class KeyBytes implements IKey {

final byte[] key;

/**
* Creates a new key from byte array.
*
* @param key byte array
*
* @throws NullArgumentException if `key` is null.
* @throws InvalidArgumentException if `key` is empty.
*/
public KeyBytes(byte[] key) {
if (key == null) {
throw new NullArgumentException("key cannot be null");
}
if (key.length == 0) {
throw new InvalidArgumentException("key cannot be empty");
}
// Copy the key so that changes in the original array do not
// affect this key.
this.key = key.clone();
}

@Override
public byte[] toByteArray() {
// Java arrays are always mutable. Return a copy to the caller
// so that their modifications do not affect the actual key.
return this.key.clone();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
public class PrivateKey extends AsymmetricKey {

/**
* Creates new private key from byte array
* Creates private key from byte array.
*
* @param key byte array
*
* @throws NullArgumentException if `key` is null.
* @throws InvalidArgumentException if `key` is empty.
*/
public PrivateKey(byte[] key) {

super(key);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
public class PublicKey extends AsymmetricKey {

/**
* Creates new public key from byte array
* Creates public key from byte array.
*
* @param key byte array
*
* @throws NullArgumentException if `key` is null.
* @throws InvalidArgumentException if `key` is empty.
*/
public PublicKey(byte[] key) {

super(key);

}

}

0 comments on commit 8fe48f5

Please sign in to comment.