com.amazonaws.encryptionsdk.model.KeyBlob Maven / Gradle / Ivy
/*
* Copyright 2016 Amazon.com, Inc. or its affiliates. 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. A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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.amazonaws.encryptionsdk.model;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import com.amazonaws.encryptionsdk.EncryptedDataKey;
import com.amazonaws.encryptionsdk.exception.AwsCryptoException;
import com.amazonaws.encryptionsdk.exception.ParseException;
import com.amazonaws.encryptionsdk.internal.Constants;
import com.amazonaws.encryptionsdk.internal.PrimitivesParser;
/**
* This class implements the format of the key blob. The format contains the
* following fields in order:
*
* -
* length of key provider
* -
* key provider
* -
* length of key provider info
* -
* key provider info
* -
* length of encrypted key
* -
* encrypted key
*
*/
//@ nullable_by_default
public final class KeyBlob implements EncryptedDataKey {
private int keyProviderIdLen_ = -1; //@ in providerId;
private byte[] keyProviderId_; //@ in providerId;
private int keyProviderInfoLen_ = -1; //@ in providerInformation;
private byte[] keyProviderInfo_; //@ in providerInformation;
private int encryptedKeyLen_ = -1; //@ in encryptedDataKey;
private byte[] encryptedKey_; //@ in encryptedDataKey;
//@ private invariant keyProviderIdLen_ <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ private invariant keyProviderInfoLen_ <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ private invariant encryptedKeyLen_ <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@// KeyBlob implements EncryptedDataKey, which defines three model fields.
//@// For a KeyBlob, these model fields correspond directly to some underlying
//@// Java fields, as expressed by the following "represents" declarations:
//@ private represents providerId = keyProviderId_;
//@ private represents providerInformation = keyProviderInfo_;
//@ private represents encryptedDataKey = encryptedKey_;
//@// As mentioned in EncryptedDataKey, deserialization goes through some
//@// incomplete intermediate states. The ghost field "deserializing" keeps
//@// track of these states:
//@ private ghost int deserializing;
//@ private invariant 0 <= deserializing && deserializing < 4;
//@// The abstract "isDeserializing", defined in EncryptedDataKey, is represented
//@// as "true" whenever "deserializing" is non-0.
//@ private represents isDeserializing = deserializing != 0;
//@// The fields of KeyBlob come in pairs, for example, "keyProviderId_" and
//@// "keyProviderIdLen_". Generally, the latter stores the length of the former.
//@// But this is not always so. For one, if the former is "null", then the latter
//@// is -1. Also, this relationship the two fields does not hold in one of the
//@// incomplete intermediate deserialization states. Therefore, the invariants
//@// about these fields are as follows:
//@ private invariant deserializing == 1 || keyProviderIdLen_ == (keyProviderId_ == null ? -1 : keyProviderId_.length);
//@ private invariant deserializing == 2 || keyProviderInfoLen_ == (keyProviderInfo_ == null ? -1 : keyProviderInfo_.length);
//@ private invariant deserializing == 3 || encryptedKeyLen_ == (encryptedKey_ == null ? -1 : encryptedKey_.length);
//@// In the incomplete intermediate states, other specific properties hold about the
//@// fields, as expressed in the following invariants:
//@ private invariant deserializing == 1 ==> 0 <= keyProviderIdLen_ && keyProviderId_ == null;
//@ private invariant deserializing == 2 ==> 0 <= keyProviderIdLen_ && 0 <= keyProviderInfoLen_ && keyProviderInfo_ == null;
//@ private invariant deserializing == 3 ==> 0 <= keyProviderIdLen_ && 0 <= keyProviderInfoLen_ && 0 <= encryptedKeyLen_ && encryptedKey_ == null;
//@// It is by querying the "isComplete()" method that a caller finds out if the
//@// deserialization is only partially done or is complete. The "isComplete()"
//@// method is defined later on and returns the value of the field "isComplete_".
//@// If postcondition of "deserialize()" and the following public invariant about
//@// "isComplete_" tell a client that the 3 abstract properties of the class have
//@// been initialized. Note that this invariant (and, indeed, the "isComplete()"
//@// method) does not tell a client anything useful unless "deserialize()" has been
//@// called. For example, if the 3 abstract properties of a KeyBlob have been
//@// initialized using the "set..." methods, then the result value of "isComplete()"
//@// is meaningless.
//@ spec_public
private boolean isComplete_ = false;
//@ public invariant isComplete_ && !isDeserializing ==> providerId != null && providerInformation != null && encryptedDataKey != null;
/**
* Default constructor.
*/
//@ public normal_behavior
//@ ensures providerId == null && providerInformation == null && encryptedDataKey == null;
//@ ensures !isDeserializing;
//@ pure
public KeyBlob() {
}
/**
* Construct a key blob using the provided key, key provider identifier, and
* key provider information.
* @param keyProviderId
* the key provider identifier string.
* @param keyProviderInfo
* the bytes containing the key provider info.
* @param encryptedDataKey
* the encrypted bytes of the data key.
*/
//@ public normal_behavior
//@ requires keyProviderId != null && EncryptedDataKey.s2ba(keyProviderId).length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ requires keyProviderInfo != null && keyProviderInfo.length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ requires encryptedDataKey != null && encryptedDataKey.length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ ensures \fresh(providerId);
//@ ensures Arrays.equalArrays(providerId, EncryptedDataKey.s2ba(keyProviderId));
//@ ensures \fresh(providerInformation);
//@ ensures Arrays.equalArrays(providerInformation, keyProviderInfo);
//@ ensures \fresh(this.encryptedDataKey);
//@ ensures Arrays.equalArrays(this.encryptedDataKey, encryptedDataKey);
//@ ensures !isDeserializing;
//@ also
//@ public exceptional_behavior
//@ requires keyProviderId != null && keyProviderInfo != null && encryptedDataKey != null;
//@ requires Constants.UNSIGNED_SHORT_MAX_VAL < EncryptedDataKey.s2ba(keyProviderId).length || Constants.UNSIGNED_SHORT_MAX_VAL < keyProviderInfo.length || Constants.UNSIGNED_SHORT_MAX_VAL < encryptedDataKey.length;
//@ signals_only AwsCryptoException;
//@ pure
public KeyBlob(final String keyProviderId, final byte[] keyProviderInfo, final byte[] encryptedDataKey) {
setEncryptedDataKey(encryptedDataKey);
setKeyProviderId(keyProviderId);
setKeyProviderInfo(keyProviderInfo);
}
//@ public normal_behavior
//@ requires edk != null && !edk.isDeserializing;
//@ requires edk.providerId != null && EncryptedDataKey.ba2s2ba(edk.providerId).length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ requires edk.providerInformation != null && edk.providerInformation.length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ requires edk.encryptedDataKey != null && edk.encryptedDataKey.length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ ensures \fresh(providerId);
//@ ensures Arrays.equalArrays(providerId, EncryptedDataKey.ba2s2ba(edk.providerId));
//@ ensures \fresh(providerInformation);
//@ ensures Arrays.equalArrays(providerInformation, edk.providerInformation);
//@ ensures \fresh(encryptedDataKey);
//@ ensures Arrays.equalArrays(encryptedDataKey, edk.encryptedDataKey);
//@ ensures !isDeserializing;
//@ also
//@ public exceptional_behavior
//@ requires edk != null && !edk.isDeserializing;
//@ requires edk.providerId != null && edk.providerInformation != null && edk.encryptedDataKey != null;
//@ requires Constants.UNSIGNED_SHORT_MAX_VAL < EncryptedDataKey.ba2s2ba(edk.providerId).length || Constants.UNSIGNED_SHORT_MAX_VAL < edk.providerInformation.length || Constants.UNSIGNED_SHORT_MAX_VAL < edk.encryptedDataKey.length;
//@ signals_only AwsCryptoException;
//@ pure
public KeyBlob(final EncryptedDataKey edk) {
setEncryptedDataKey(edk.getEncryptedDataKey());
String s = edk.getProviderId();
//@ set EncryptedDataKey.lemma_s2ba_depends_only_string_contents_only(s, EncryptedDataKey.ba2s(edk.providerId));
setKeyProviderId(s);
setKeyProviderInfo(edk.getProviderInformation());
}
/**
* Parse the key provider identifier length in the provided bytes. It looks
* for 2 bytes representing a short primitive type in the provided bytes
* starting at the specified off.
*
*
* If successful, it returns the size of the parsed bytes which is the size
* of the short primitive type. On failure, it throws a parse exception.
*
* @param b
* the byte array to parse.
* @param off
* the offset in the byte array to use when parsing.
* @return
* the size of the parsed bytes which is the size of the short
* primitive.
* @throws ParseException
* if there are not sufficient bytes to parse the identifier
* length.
*/
//@ private normal_behavior
//@ requires deserializing == 0 && keyProviderId_ == null;
//@ requires b != null && 0 <= off && off <= b.length - Short.BYTES;
//@ assignable keyProviderIdLen_, deserializing, isDeserializing;
//@ ensures \result == Short.BYTES && deserializing == 1;
//@ also
//@ private exceptional_behavior
//@ requires keyProviderId_ == null;
//@ requires b != null && 0 <= off && b.length - Short.BYTES < off;
//@ assignable \nothing;
//@ signals_only ParseException;
private int parseKeyProviderIdLen(final byte[] b, final int off) throws ParseException {
keyProviderIdLen_ = PrimitivesParser.parseUnsignedShort(b, off);
//@ set deserializing = 1;
return Short.SIZE / Byte.SIZE;
}
/**
* Parse the key provider identifier in the provided bytes. It looks
* for bytes of size defined by the key provider identifier length in the
* provided bytes starting at the specified off.
*
*
* If successful, it returns the size of the parsed bytes which is the key
* provider identifier length. On failure, it throws a parse exception.
*
* @param b
* the byte array to parse.
* @param off
* the offset in the byte array to use when parsing.
* @return
* the size of the parsed bytes which is the key provider identifier
* length.
* @throws ParseException
* if there are not sufficient bytes to parse the identifier.
*/
//@ private normal_behavior
//@ requires deserializing == 1 && b != null && 0 <= off && off <= b.length;
//@ requires keyProviderIdLen_ <= b.length - off;
//@ assignable keyProviderId_, deserializing, isDeserializing;
//@ ensures \result == keyProviderIdLen_ && deserializing == 0;
//@ ensures keyProviderId_ != null && keyProviderId_.length == keyProviderIdLen_;
//@ also
//@ private exceptional_behavior
//@ requires deserializing == 1 && b != null && 0 <= off && off <= b.length;
//@ requires b.length - off < keyProviderIdLen_;
//@ assignable \nothing;
//@ signals_only ParseException;
private int parseKeyProviderId(final byte[] b, final int off) throws ParseException {
final int bytesToParseLen = b.length - off;
if (bytesToParseLen >= keyProviderIdLen_) {
keyProviderId_ = Arrays.copyOfRange(b, off, off + keyProviderIdLen_);
//@ set deserializing = 0;
return keyProviderIdLen_;
} else {
throw new ParseException("Not enough bytes to parse key provider id");
}
}
/**
* Parse the key provider info length in the provided bytes. It looks
* for 2 bytes representing a short primitive type in the provided bytes
* starting at the specified off.
*
*
* If successful, it returns the size of the parsed bytes which is the size
* of the short primitive type. On failure, it throws a parse exception.
*
* @param b
* the byte array to parse.
* @param off
* the offset in the byte array to use when parsing.
* @return
* the size of the parsed bytes which is the size of the short
* primitive type.
* @throws ParseException
* if there are not sufficient bytes to parse the provider info
* length.
*/
//@ private normal_behavior
//@ requires deserializing == 0 && 0 <= keyProviderIdLen_ && keyProviderInfo_ == null;
//@ requires b != null && 0 <= off && off <= b.length - Short.BYTES;
//@ assignable keyProviderInfoLen_, deserializing, isDeserializing;
//@ ensures \result == Short.BYTES && deserializing == 2;
//@ also
//@ private exceptional_behavior
//@ requires deserializing == 0 && 0 <= keyProviderIdLen_ && keyProviderInfo_ == null;
//@ requires b != null && 0 <= off && b.length - Short.BYTES < off;
//@ assignable \nothing;
//@ signals_only ParseException;
private int parseKeyProviderInfoLen(final byte[] b, final int off) throws ParseException {
keyProviderInfoLen_ = PrimitivesParser.parseUnsignedShort(b, off);
//@ set deserializing = 2;
return Short.SIZE / Byte.SIZE;
}
/**
* Parse the key provider info in the provided bytes. It looks for bytes of
* size defined by the key provider info length in the provided bytes
* starting at the specified off.
*
*
* If successful, it returns the size of the parsed bytes which is the key
* provider info length. On failure, it throws a parse exception.
*
* @param b
* the byte array to parse.
* @param off
* the offset in the byte array to use when parsing.
* @return
* the size of the parsed bytes which is the key provider info
* length.
* @throws ParseException
* if there are not sufficient bytes to parse the provider info.
*/
//@ private normal_behavior
//@ requires deserializing == 2 && b != null && 0 <= off && off <= b.length;
//@ requires keyProviderInfoLen_ <= b.length - off;
//@ assignable keyProviderInfo_, deserializing, isDeserializing;
//@ ensures \result == keyProviderInfoLen_ && deserializing == 0;
//@ ensures keyProviderInfo_ != null && keyProviderInfo_.length == keyProviderInfoLen_;
//@ also
//@ private exceptional_behavior
//@ requires deserializing == 2 && b != null && 0 <= off && off <= b.length;
//@ requires b.length - off < keyProviderInfoLen_;
//@ assignable \nothing;
//@ signals_only ParseException;
private int parseKeyProviderInfo(final byte[] b, final int off) throws ParseException {
final int bytesToParseLen = b.length - off;
if (bytesToParseLen >= keyProviderInfoLen_) {
keyProviderInfo_ = Arrays.copyOfRange(b, off, off + keyProviderInfoLen_);
//@ set deserializing = 0;
return keyProviderInfoLen_;
} else {
throw new ParseException("Not enough bytes to parse key provider info");
}
}
/**
* Parse the key length in the provided bytes. It looks for 2 bytes
* representing a short primitive type in the provided bytes starting at the
* specified off.
*
*
* If successful, it returns the size of the parsed bytes which is the size
* of the short primitive type. On failure, it throws a parse exception.
*
* @param b
* the byte array to parse.
* @param off
* the offset in the byte array to use when parsing.
* @return
* the size of the parsed bytes which is the size of the short
* primitive type.
* @throws ParseException
* if there are not sufficient bytes to parse the key length.
*/
//@ private normal_behavior
//@ requires deserializing == 0 && 0 <= keyProviderIdLen_ && 0 <= keyProviderInfoLen_ && encryptedKey_ == null;
//@ requires b != null && 0 <= off && off <= b.length - Short.BYTES;
//@ assignable encryptedKeyLen_, deserializing, isDeserializing;
//@ ensures \result == Short.BYTES && deserializing == 3;
//@ also
//@ private exceptional_behavior
//@ requires deserializing == 0 && 0 <= keyProviderIdLen_ && 0 <= keyProviderInfoLen_ && encryptedKey_ == null;
//@ requires b != null && 0 <= off && b.length - Short.BYTES < off;
//@ assignable \nothing;
//@ signals_only ParseException;
private int parseKeyLen(final byte[] b, final int off) throws ParseException {
encryptedKeyLen_ = PrimitivesParser.parseUnsignedShort(b, off);
//@ set deserializing = 3;
return Short.SIZE / Byte.SIZE;
}
/**
* Parse the key in the provided bytes. It looks for bytes of size defined
* by the key length in the provided bytes starting at the specified off.
*
*
* If successful, it returns the size of the parsed bytes which is the key
* length. On failure, it throws a parse exception.
*
* @param b
* the byte array to parse.
* @param off
* the offset in the byte array to use when parsing.
* @return
* the size of the parsed bytes which is the key length.
* @throws ParseException
* if there are not sufficient bytes to parse the key.
*/
//@ private normal_behavior
//@ requires deserializing == 3 && b != null && 0 <= off && off <= b.length;
//@ requires encryptedKeyLen_ <= b.length - off;
//@ assignable encryptedKey_, deserializing, isDeserializing;
//@ ensures \result == encryptedKeyLen_ && deserializing == 0;
//@ ensures encryptedKey_ != null && encryptedKey_.length == encryptedKeyLen_;
//@ also
//@ private exceptional_behavior
//@ requires deserializing == 3 && b != null && 0 <= off && off <= b.length;
//@ requires b.length - off < encryptedKeyLen_;
//@ assignable \nothing;
//@ signals_only ParseException;
private int parseKey(final byte[] b, final int off) throws ParseException {
final int bytesToParseLen = b.length - off;
if (bytesToParseLen >= encryptedKeyLen_) {
encryptedKey_ = Arrays.copyOfRange(b, off, off + encryptedKeyLen_);
//@ set deserializing = 0;
return encryptedKeyLen_;
} else {
throw new ParseException("Not enough bytes to parse key");
}
}
/**
* Deserialize the provided bytes starting at the specified offset to
* construct an instance of this class.
*
*
* This method parses the provided bytes for the individual fields in this
* class. This methods also supports partial parsing where not all the bytes
* required for parsing the fields successfully are available.
*
* @param b
* the byte array to deserialize.
* @param off
* the offset in the byte array to use for deserialization.
* @return
* the number of bytes consumed in deserialization.
*
*/
//@ public normal_behavior
//@ requires b == null;
//@ assignable \nothing;
//@ ensures \result == 0;
//@ also
//@ public normal_behavior
//@ requires !isComplete_;
//@ requires b != null && 0 <= off && off <= b.length;
//@ assignable this.*;
//@ ensures 0 <= \result && \result <= b.length - off;
//@ ensures isComplete_ ==> !isDeserializing;
public int deserialize(final byte[] b, final int off) {
if (b == null) {
return 0;
}
int parsedBytes = 0;
try {
if (keyProviderIdLen_ < 0) {
parsedBytes += parseKeyProviderIdLen(b, off + parsedBytes);
}
if (keyProviderId_ == null) {
parsedBytes += parseKeyProviderId(b, off + parsedBytes);
}
if (keyProviderInfoLen_ < 0) {
parsedBytes += parseKeyProviderInfoLen(b, off + parsedBytes);
}
if (keyProviderInfo_ == null) {
parsedBytes += parseKeyProviderInfo(b, off + parsedBytes);
}
if (encryptedKeyLen_ < 0) {
parsedBytes += parseKeyLen(b, off + parsedBytes);
}
if (encryptedKey_ == null) {
parsedBytes += parseKey(b, off + parsedBytes);
}
isComplete_ = true;
} catch (ParseException e) {
// this results when we do partial parsing and there aren't enough
// bytes to parse; ignore it and return the bytes parsed thus far.
}
return parsedBytes;
}
/**
* Serialize an instance of this class to a byte array.
*
* @return
* the serialized bytes of the instance.
*/
//@ public normal_behavior
//@ requires !isDeserializing;
//@ requires providerId != null;
//@ requires providerInformation != null;
//@ requires encryptedDataKey != null;
//@ assignable \nothing;
//@ ensures \fresh(\result);
//@ ensures \result.length == 3 * Short.BYTES + providerId.length + providerInformation.length + encryptedDataKey.length;
//@ code_java_math // necessary, or else casts to short are warnings
public byte[] toByteArray() {
final int outLen = 3 * (Short.SIZE / Byte.SIZE) + keyProviderIdLen_ + keyProviderInfoLen_ + encryptedKeyLen_;
final ByteBuffer out = ByteBuffer.allocate(outLen);
out.putShort((short) keyProviderIdLen_);
out.put(keyProviderId_, 0, keyProviderIdLen_);
out.putShort((short) keyProviderInfoLen_);
out.put(keyProviderInfo_, 0, keyProviderInfoLen_);
out.putShort((short) encryptedKeyLen_);
out.put(encryptedKey_, 0, encryptedKeyLen_);
return out.array();
}
/**
* Check if this object has all the header fields populated and available
* for reading.
*
* @return
* true if this object containing the single block header fields
* is complete; false otherwise.
*/
//@ public normal_behavior
//@ ensures \result == isComplete_;
//@ pure
public boolean isComplete() {
return isComplete_;
}
/**
* Return the length of the key provider identifier set in the header.
*
* @return
* the length of the key provider identifier.
*/
//@ public normal_behavior
//@ requires !isDeserializing;
//@ ensures providerId == null ==> \result < 0;
//@ ensures providerId != null ==> \result == providerId.length;
//@ pure
public int getKeyProviderIdLen() {
return keyProviderIdLen_;
}
/**
* Return the key provider identifier set in the header.
*
* @return
* the string containing the key provider identifier.
*/
@Override
public String getProviderId() {
String s = new String(keyProviderId_, StandardCharsets.UTF_8);
// The following assume statement essentially says that different
// calls to the String constructor above, with the same parameters,
// result in strings with the same contents. The assumption is
// needed, because JML does not give a way to prove it.
//@ assume String.equals(s, EncryptedDataKey.ba2s(keyProviderId_));
return s;
}
/**
* Return the length of the key provider info set in the header.
*
* @return
* the length of the key provider info.
*/
//@ public normal_behavior
//@ requires !isDeserializing;
//@ ensures providerInformation == null ==> \result < 0;
//@ ensures providerInformation != null ==> \result == providerInformation.length;
//@ pure
public int getKeyProviderInfoLen() {
return keyProviderInfoLen_;
}
/**
* Return the information on the key provider set in the header.
*
* @return
* the bytes containing information on the key provider.
*/
@Override
public byte[] getProviderInformation() {
return keyProviderInfo_.clone();
}
/**
* Return the length of the encrypted data key set in the header.
*
* @return
* the length of the encrypted data key.
*/
//@ public normal_behavior
//@ requires !isDeserializing;
//@ ensures encryptedDataKey == null ==> \result < 0;
//@ ensures encryptedDataKey != null ==> \result == encryptedDataKey.length;
//@ pure
public int getEncryptedDataKeyLen() {
return encryptedKeyLen_;
}
/**
* Return the encrypted data key set in the header.
*
* @return
* the bytes containing the encrypted data key.
*/
@Override
public byte[] getEncryptedDataKey() {
return encryptedKey_.clone();
}
/**
* Set the key provider identifier.
*
* @param keyProviderId
* the key provider identifier.
*/
//@ public normal_behavior
//@ requires !isDeserializing;
//@ requires keyProviderId != null && EncryptedDataKey.s2ba(keyProviderId).length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ assignable providerId;
//@ ensures \fresh(providerId);
//@ ensures Arrays.equalArrays(providerId, EncryptedDataKey.s2ba(keyProviderId));
//@ also
//@ private normal_behavior // TODO: this behavior is a temporary workaround
//@ requires !isDeserializing;
//@ requires keyProviderId != null && EncryptedDataKey.s2ba(keyProviderId).length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ assignable keyProviderId_, keyProviderIdLen_;
//@ also
//@ public exceptional_behavior
//@ requires !isDeserializing;
//@ requires keyProviderId != null && Constants.UNSIGNED_SHORT_MAX_VAL < EncryptedDataKey.s2ba(keyProviderId).length;
//@ assignable \nothing;
//@ signals_only AwsCryptoException;
public void setKeyProviderId(final String keyProviderId) {
final byte[] keyProviderIdBytes = keyProviderId.getBytes(StandardCharsets.UTF_8);
//@ assume Arrays.equalArrays(keyProviderIdBytes, EncryptedDataKey.s2ba(keyProviderId));
if (keyProviderIdBytes.length > Constants.UNSIGNED_SHORT_MAX_VAL) {
throw new AwsCryptoException(
"Key provider identifier length exceeds the max value of an unsigned short primitive.");
}
keyProviderId_ = keyProviderIdBytes;
keyProviderIdLen_ = keyProviderId_.length;
}
/**
* Set the information on the key provider identifier.
*
* @param keyProviderInfo
* the bytes containing information on the key provider
* identifier.
*/
//@ public normal_behavior
//@ requires !isDeserializing;
//@ requires keyProviderInfo != null && keyProviderInfo.length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ assignable providerInformation;
//@ ensures \fresh(providerInformation);
//@ ensures Arrays.equalArrays(providerInformation, keyProviderInfo);
//@ also
//@ private normal_behavior // TODO: this behavior is a temporary workaround
//@ requires !isDeserializing;
//@ requires keyProviderInfo != null && keyProviderInfo.length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ assignable keyProviderInfo_, keyProviderInfoLen_;
//@ also private exceptional_behavior
//@ requires !isDeserializing;
//@ requires keyProviderInfo != null;
//@ requires keyProviderInfo.length > Constants.UNSIGNED_SHORT_MAX_VAL;
//@ assignable \nothing;
//@ signals_only AwsCryptoException;
public void setKeyProviderInfo(final byte[] keyProviderInfo) {
if (keyProviderInfo.length > Constants.UNSIGNED_SHORT_MAX_VAL) {
throw new AwsCryptoException(
"Key provider identifier information length exceeds the max value of an unsigned short primitive.");
}
keyProviderInfo_ = keyProviderInfo.clone();
keyProviderInfoLen_ = keyProviderInfo.length;
}
/**
* Set the encrypted data key.
*
* @param encryptedDataKey
* the bytes containing the encrypted data key.
*/
//@ public normal_behavior
//@ requires !isDeserializing;
//@ requires encryptedDataKey != null && encryptedDataKey.length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ assignable this.encryptedDataKey;
//@ ensures \fresh(this.encryptedDataKey);
//@ ensures Arrays.equalArrays(this.encryptedDataKey, encryptedDataKey);
//@ also
//@ private normal_behavior // TODO: this behavior is a temporary workaround
//@ requires !isDeserializing;
//@ requires encryptedDataKey != null && encryptedDataKey.length <= Constants.UNSIGNED_SHORT_MAX_VAL;
//@ assignable encryptedKey_, encryptedKeyLen_;
//@ also
//@ public exceptional_behavior
//@ requires !isDeserializing;
//@ requires encryptedDataKey != null;
//@ requires encryptedDataKey.length > Constants.UNSIGNED_SHORT_MAX_VAL;
//@ assignable \nothing;
//@ signals_only AwsCryptoException;
public void setEncryptedDataKey(final byte[] encryptedDataKey) {
if (encryptedDataKey.length > Constants.UNSIGNED_SHORT_MAX_VAL) {
throw new AwsCryptoException("Key length exceeds the max value of an unsigned short primitive.");
}
encryptedKey_ = encryptedDataKey.clone();
encryptedKeyLen_ = encryptedKey_.length;
}
}