Symlink securemessage headers

This commit is contained in:
deling-google
2022-03-31 14:55:51 -07:00
parent 47d07ea29f
commit 0127c862a8
11 changed files with 1 additions and 4335 deletions
+1
View File
@@ -0,0 +1 @@
../securemessage/cpp/include/securemessage
@@ -1,140 +0,0 @@
/*
* 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.
*/
//
// A utility class for helping to interact with contiguous memory regions in a
// way that's both c++ friendly and works with OpenSSL's legacy C requirements.
//
// Will securely destroy enclosed data when deallocated
//
#ifndef SECUREMESSAGE_BYTE_BUFFER_H_
#define SECUREMESSAGE_BYTE_BUFFER_H_
#include <stddef.h>
#include <cstdint>
#include <memory>
#include <vector>
#include "securemessage/common.h"
namespace securemessage {
class ByteBuffer {
public:
// Create an empty byte buffer
ByteBuffer();
// Create a buffer of a certain size. Buffer will be filled with zeros.
explicit ByteBuffer(size_t size);
// Create a buffer initialized with bytes from a string
explicit ByteBuffer(const string& source_data);
// Create a buffer initialized with data from a const char* and a length
explicit ByteBuffer(const char* source_data, size_t length);
// Create a buffer initialized with data from a const char* (assumes null
// termination)
explicit ByteBuffer(const char* source_data);
// Create a buffer initialized with data from a uint8_t
explicit ByteBuffer(const uint8_t* source_data, size_t length);
// Fill with the specified data. Any old data is discarded
void SetData(const uint8_t* source_data, size_t length);
// Appends num_bytes of value byte to the end of the existing data
// Currently may violate secure memory guarantees by leaking some data on the
// heap
void Append(size_t num_bytes, const uint8_t byte);
// Prepends a string to the beginning of this ByteBuffer
// Currently may violate secure memory guarantees by leaking some data on the
// heap
void Prepend(const string& str);
// Concatenates two byte buffers. Placing a before b. If a is empty, then
// the result will be b. If b is empty, the result will be a. If both are
// empty, the result will be an empty byte buffer.
static ByteBuffer Concat(const ByteBuffer& a, const ByteBuffer& b);
// Get size of internal buffer
size_t size() const;
// Returns a unique pointer to new ByteBuffer of a given length starting from
// a given offset.
// Returns a unique pointer to an empty ByteBuffer if length is 0.
// Returns a nullptr if the specified parameters are invalid.
// Note that valid offset begins at 0
std::unique_ptr<ByteBuffer> SubArray(size_t offset, size_t length) const;
// Get mutable memory as unsigned char*
unsigned char* MutableUChar();
// Get immutable memory as unsigned char*
unsigned const char* ImmutableUChar() const;
// Get mutable memory as uint8_t*
uint8_t* MutableUInt8();
// Get immutable memory as uint8_t*
const uint8_t* ImmutableUInt8() const;
// Get a copy of the memory in a C++ string
string String() const;
// Get a copy of the memory in a C++ vector
std::vector<uint8_t> Vector() const;
// Returns true if the bytes in the other buffer are the same as in this
// buffer, false otherwise. Note: This function does NOT perform an early exit
// when it encounters a mismatching element in order to guard against timing
// attacks.
bool Equals(const ByteBuffer& other) const;
// Returns true if the bytes in the other string are the same as in this
// buffer, false otherwise. Note: This function does NOT perform an early exit
// when it encounters a mismatching element in order to guard against timing
// attacks.
bool Equals(const string& other) const;
// Returns a copy of the data as a printable hex string -- for easy debugging
string AsDebugHexString() const;
// Securely resets the ByteBuffer by securely deleting any stored data.
void Clear();
// Securely destroys the ByteBuffer
~ByteBuffer();
private:
// We rely on the fact that vectors are guaranteed to use contiguous memory
// for storing elements.
// TODO(aczeskis): define a custom version of vector that has a wiping
// deallocator.
std::vector<uint8_t> data_;
// Overwrites all elements in data vector one time. Does not resize data
// vector.
void Wipe();
// Helper function to wipe a specified buffer.
void WipeBuffer(uint8_t* buffer, size_t length);
};
} // namespace securemessage
#endif // SECUREMESSAGE_BYTE_BUFFER_H_
@@ -1,26 +0,0 @@
/*
* 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.
*/
#ifndef SECUREMESSAGE_COMMON_H_
#define SECUREMESSAGE_COMMON_H_
#include <string>
#ifndef HAS_GLOBAL_STRING
using std::string;
#endif
#endif // SECUREMESSAGE_COMMON_H_
@@ -1,503 +0,0 @@
/*
* 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.
*/
#ifndef SECUREMESSAGE_CRYPTO_OPS_H_
#define SECUREMESSAGE_CRYPTO_OPS_H_
#include <cstdint>
#include <memory>
#include <string>
#include "securemessage/byte_buffer.h"
#include "securemessage/common.h"
namespace securemessage {
//
// Encapsulates the cryptographic operations used by the {@code SecureMessage*}
// classes.
//
class CryptoOps {
public:
//
// Enum of supported signature schemes.
//
enum SigType {
HMAC_SHA256,
ECDSA_P256_SHA256,
RSA2048_SHA256,
SIG_TYPE_END // used for testing
};
//
// Enum of supported encryption types
//
enum EncType {
NONE,
AES_256_CBC,
ENC_TYPE_END // used for testing
};
//
// Key Algorithms we support
//
enum KeyAlgorithm {
AES_256_KEY,
ECDSA_KEY,
RSA_KEY
};
//
// Key Types we believe to exist
//
enum KeyType {
PUBLIC,
PRIVATE,
SECRET
};
//
// Represents a base key class, SecretKey and PublicKey are derived from this
// class
//
class Key {
public:
//
// The default constructor is deleted so that class consumers cannot create
// a generic key class. They must use a particular key type class.
//
Key() = delete;
ByteBuffer data() { return data_; }
const ByteBuffer& data() const { return data_; }
KeyAlgorithm algorithm() const { return algorithm_; }
KeyType type() const { return type_; }
protected:
//
// Constructor cannot be called so that consumers can't simply create a
// generic key. Instead, they must use a particular key type class.
//
Key(const ByteBuffer& data, KeyAlgorithm algorithm, KeyType type) {
data_ = data;
algorithm_ = algorithm;
type_ = type;
}
ByteBuffer data_;
KeyAlgorithm algorithm_;
KeyType type_;
};
//
// We have three key types: Public, Private, and Secret (symmetric)
//
class PublicKey : public Key {
public:
PublicKey(const string& data, KeyAlgorithm algorithm)
: Key(ByteBuffer(data), algorithm, PUBLIC) {}
PublicKey(const ByteBuffer& data, KeyAlgorithm algorithm)
: Key(data, algorithm, PUBLIC) {}
};
class PrivateKey : public Key {
public:
PrivateKey(const string& data, KeyAlgorithm algorithm)
: Key(ByteBuffer(data), algorithm, PRIVATE) {}
PrivateKey(const ByteBuffer& data, KeyAlgorithm algorithm)
: Key(data, algorithm, PRIVATE) {}
};
class SecretKey : public Key {
public:
SecretKey(const string& data, KeyAlgorithm algorithm)
: Key(ByteBuffer(data), algorithm, SECRET) {}
SecretKey(const ByteBuffer& data, KeyAlgorithm algorithm)
: Key(data, algorithm, SECRET) {}
};
struct KeyPair {
std::unique_ptr<PrivateKey> private_key;
std::unique_ptr<PublicKey> public_key;
KeyPair(std::unique_ptr<PublicKey> pub,
std::unique_ptr<PrivateKey> priv) {
public_key = std::move(pub);
private_key = std::move(priv);
}
};
//
// Implements HKDF (RFC 5869) with the SHA-256 hash and a 256-bit output key
// length.
//
// @param inputKeyMaterial master key from which to derive sub-keys
// @param salt a (public) randomly generated 256-bit input that can be re-used
// @param info arbitrary information that is bound to the derived key (i.e.,
// used in its creation)
// @return a std::unique_ptr<string> holding the derived key bytes =
// HKDF-SHA256(inputKeyMaterial, salt, info) on success or nullptr on error
//
static std::unique_ptr<string> Hkdf(const string& inputKeyMaterial,
const string& salt,
const string& info);
//
// A key derivation function specific to this library, which accepts a {@code
// masterKey} and an arbitrary {@code purpose} describing the intended
// application of the derived sub-key, and produces a derived AES - 256 key
// safe to use as if it were independent of any other derived key which used
// a different {@code purpose}.
//
// @param masterKey any key suitable for use with HmacSHA256
// @param purpose a UTF-8 encoded string describing the intended purpose of
// derived key
// @return a derived Key suitable for use with AES-256
//
static std::unique_ptr<SecretKey> DeriveAes256KeyFor(
const SecretKey& masterKey, const string& purpose);
//
// SHA 256 length, in bytes
//
static const unsigned int kSha256DigestSize = 32;
//
// Salt length, in bytes
//
static const unsigned int kSaltSize = 32;
// AES 256 key length, in bytes
static const unsigned int kAesKeySize = 32;
//
// Truncated hash output length, in bytes.
//
static const unsigned int kDigestLength = 20;
//
// Computes a collision-resistant hash of {@link #kDigestLength} bytes
// (using a truncated SHA-256 output).
//
// @return a std::unique_ptr holding the digest or a nullptr on error
//
static std::unique_ptr<string> Digest(const string& data);
//
// Decrypts {@code ciphertext} using the algorithm specified in {@code
// encType}, with the specified {@code iv} and {@code decryptionKey}.
//
// @return a std::unique_ptr holding the decrypted data or a nullptr on error
//
static std::unique_ptr<string> Decrypt(const SecretKey& decryptionKey,
EncType encType,
const string& iv,
const string& ciphertext);
//
// Encrypts {@code plaintext} using the algorithm specified in {@code
// encType}, with the specified * {@code iv} and {@code encryptionKey}.
//
// @param rng source of randomness to be used with the specified cipher, if
// necessary
// @return a std::unique_ptr holding the encrypted data or nullptr on error
static std::unique_ptr<string> Encrypt(const SecretKey& encryptionKey,
EncType encType,
const string& iv,
const string& plaintext);
//
// Runs the Diffie-Hellman algorithm.
//
// @param private_key must have the same algorithm as the peer_key
// @param peer_key must be the matching public key
// @return an AES secret key created from the SHA-256 of the secret created
// here or nullptr on error.
//
static std::unique_ptr<SecretKey> KeyAgreementSha256(
const PrivateKey& private_key,
const PublicKey& peer_key);
//
// Generate a random IV appropriate for use with the algorithm specified in
// {@code encType}.
//
// @return a freshly generated IV (a random byte sequence of appropriate
// length)
//
static std::unique_ptr<string> GenerateIv(EncType encType);
//
// Signs {@code data} using the algorithm specified by {@code sigType} with
// {@code signingKey}.
//
// @param rng is required for public key signature schemes
// @return a std::unique_ptr holding a string that represents the raw
// signature or a nullptr on error
//
static std::unique_ptr<string> Sign(SigType sigType,
const Key& signingKey,
const string& data);
//
// Verifies the {@code signature} on {@code data} using the algorithm
// specified by {@code sigType} with {@code verificationKey}.
//
// @return true iff the signature is verified
//
static bool Verify(SigType sigType,
const Key& verificationKey,
const string& signature,
const string& data);
//
// Imports a P256 EC Public Key using the x and y coordinates of the curve.
//
// @return nullptr if the point is invalid
//
static std::unique_ptr<PublicKey> ImportEcP256Key(const string& x,
const string& y);
//
// Exports the x and y coordinates of a P256 EC Public Key.
//
// @return false iff the key cannot be exported (for example, incorrect type)
//
static bool ExportEcP256Key(const PublicKey& key, string *x, string *y);
//
// Imports a 2048 bit RSA Public Key using the modulus {@code n} and exponent
// {@code e}.
//
// @return nullptr if the parameters are invalid
//
static std::unique_ptr<PublicKey> ImportRsa2048Key(const string& n,
int32_t e);
//
// Exports the modulus and exponent of a 2048 bit RSA Public Key.
//
// @return false iff the key cannot be exported (for example, incorrect type)
//
static bool ExportRsa2048Key(const PublicKey& key, string* n, int32_t* e);
//
// Returns true if a sigType is a public key scheme
//
static bool IsPublicKeyScheme(SigType sigType);
//
// Indicates whether a "tag" is needed next to the plaintext body inside the
// ciphertext, to prevent the same ciphertext from being reused with someone
// else's signature on it.
//
static bool TaggedPlaintextRequired(const Key& signing_key,
SigType sig_type,
const Key& encryption_key);
// Generates a 256 bit AES secret key
static std::unique_ptr<SecretKey> GenerateAes256SecretKey();
// Generates a P256 EC key pair
static std::unique_ptr<KeyPair> GenerateEcP256KeyPair();
// Generates a 2048 bit RSA key pair
static std::unique_ptr<KeyPair> GenerateRsa2048KeyPair();
//
// @return SHA-256(UTF-8 encoded input)
//
// Will return a 32 byte ByteBuffer representing the SHA256 of the input bytes
// Will return a nullptr if an internal error occurs
//
static std::unique_ptr<ByteBuffer> Sha256(const ByteBuffer& message);
//
// @return SHA-512(UTF-8 encoded input)
//
// Will return a 64 byte ByteBuffer representing the SHA512 of the input bytes
// Will return a nullptr if an internal error occurs
//
static std::unique_ptr<ByteBuffer> Sha512(const ByteBuffer& message);
// Returns a ByteBuffer of |length|, which is filled with securely generated
// random values.
static std::unique_ptr<ByteBuffer> SecureRandom(size_t length);
private:
//
// @return SHA256HMAC of specified message using provided key or nullptr on
// error
static std::unique_ptr<ByteBuffer> Sha256hmac(const ByteBuffer& key,
const ByteBuffer& message);
//
// A salt value specific to this library, generated as
// SHA-256("SecureMessage")
//
// We have to initialize salt in crypto_ops.cc because C++ doesn't allow
// initialization and declaration in the same place.
//
static const uint8_t kSalt[kSaltSize];
//
// The HKDF (RFC 5869) extraction function, using the SHA-256 hash
// function. This function is used to pre-process the inputKeyMaterial and mix
// it with the salt, producing output suitable for use with HKDF expansion
// function (which produces the actual derived key).
//
// @see #hkdfSha256Expand(ByteBuffer, ByteBuffer)
// @return a std::unique_ptr<ByteBuffer> with HMAC-SHA256(salt,
// inputKeyMaterial) (salt is the "key" for the HMAC) on success or a nullptr
// on error
//
static std::unique_ptr<ByteBuffer> HkdfSha256Extract(
const ByteBuffer& inputKeyMaterial, const ByteBuffer& salt);
//
// Special case of HKDF (RFC 5869) expansion function, using the SHA-256
// hash function and allowing for a maximum output length of 256 bits.
//
// @param pseudoRandomKey should be generated by
// {@link #hkdfSha256Expand(ByteBuffer, ByteBuffer}
// @param info arbitrary information the derived key should be bound to
// @return a std::unique_ptr<ByteBuffer> holding derived key bytes =
// HMAC-SHA256(pseudoRandomKey, info | 0x01) on success or a nullptr on
// error
//
static std::unique_ptr<ByteBuffer> HkdfSha256Expand(
const ByteBuffer& pseudoRandomKey, const ByteBuffer& info);
//
// Performs AES 256 CBC decryption of {@code ciphertext} with the specified
// {@code iv} and {@code decryptionKey}. Assumes PKCS#5 padding is used
//
// @return a std::unique_ptr holding the plaintext (decrypted) data or a
// nullptr on error
//
static std::unique_ptr<ByteBuffer> Aes256CBCDecrypt(
const SecretKey& decryptionKey,
const ByteBuffer& iv,
const ByteBuffer& ciphertext);
//
// Performs AES 256 CBC encryption of {@code plaintext} with the specified
// {@code iv} and {@code encryptionKey}. PKCS#5 is used.
//
// @return a std::unique_ptr holding the ciphertext (encrypted) data or a
// nullptr on error
//
static std::unique_ptr<ByteBuffer> Aes256CBCEncrypt(
const SecretKey& encryptionKey,
const ByteBuffer& iv,
const ByteBuffer& ciphertext);
//
// Get the purpose of an encryption scheme. Basically a string representation
// of the enum.
//
static string GetPurpose(EncType encType);
//
// Get the purpose of a signature scheme. Basically a string representation
// of the enum.
//
static string GetPurpose(SigType sigType);
// Computes the ECDSA P256 SHA 256 MAC
//
// @param data the data to be signed
// @param signingKey the ECDSA private key used for signing.
// @return std::unique_ptr holding string that represents the MAC or nullptr
// on error
//
static std::unique_ptr<ByteBuffer> EcdsaP256Sha256Sign(
const PrivateKey& private_key,
const ByteBuffer& data);
// Verifies the ECDSA P256 SHA 256 signature
//
// @param signature to be verified
// @param data the data over which the signature was computed
// @param verificationKey the ECDSA public key used for verification.
// @return bool true if signature is valid, false otherwise
//
static bool EcdsaP256Sha256Verify(const PublicKey& public_key,
const ByteBuffer& signature,
const ByteBuffer& data);
//
// Runs the Elliptic Curve variant of the Diffie-Hellman algorithm.
//
// @param private_key must have the algorithm ECDSA_KEY
// @param peer_key must have the algorithm ECDSA_KEY
// @return an AES secret key created from the SHA-256 of the secret created
// by applying ECDH to the private_key and the peer_key.
//
static std::unique_ptr<ByteBuffer> EcdhKeyAgreement(
const PrivateKey& private_key,
const PublicKey& peer_key);
// Computes the RSA 2048 SHA 256 signature
//
// @param data the data to be signed
// @param signingKey the RSA Private key used to sign the data. The key
// should be in DER form.
// @return std::unique_ptr holding string that represents the MAC or nullptr
// on error
//
// TODO(aczeskis): refactor sign and verify to be virtual functions of key
// objects
//
static std::unique_ptr<ByteBuffer> Rsa2048Sha256Sign(
const PrivateKey& private_key, const ByteBuffer& data);
// Verifies the RSA 2048 SHA 256 MAC
//
// @param signature to be verified
// @param data the data over which the signature was computed
// @param verificationKey the RSA public key used for verification
// @return bool true if signature is valid, false otherwise
//
static bool Rsa2048Sha256Verify(const PublicKey& public_key,
const ByteBuffer& signature,
const ByteBuffer& data);
static bool IsValidEcP256CoordinateEncoding(const string& bytes);
static bool IsValidRsa2048ModulusEncoding(const string& bytes);
//
// Converts int32 value to an array of bytes represented as a string. The
// bytes are in big-endian order.
//
static string Int32BytesToString(int32_t value);
//
// Converts a string of bytes to an int32 value. Fails if the bytes do not fit
// in the int32 type. The bytes are in big-endian order.
//
static bool StringToInt32Bytes(const string& value, int32_t* result);
// For testing private helper functions
friend class CryptoOpsTest;
virtual ~CryptoOps();
};
} // namespace securemessage
#endif // SECUREMESSAGE_CRYPTO_OPS_H_
File diff suppressed because it is too large Load Diff
@@ -1,68 +0,0 @@
/*
* 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.
*/
#ifndef SECUREMESSAGE_PUBLIC_KEY_PROTO_UTIL_H_
#define SECUREMESSAGE_PUBLIC_KEY_PROTO_UTIL_H_
#include <memory>
#include "securemessage/common.h"
#include "securemessage/crypto_ops.h"
#include "proto/securemessage.pb.h"
namespace securemessage {
class PublicKeyProtoUtil {
public:
//
// Encodes the internal implementation of the PublicKey into the appropriate
// protobuf format.
//
// @return nullptr if the PublicKey is not supported
//
static std::unique_ptr<GenericPublicKey> EncodePublicKey(
const CryptoOps::PublicKey& key);
//
// Transforms the protobuf format into a internal representation of a
// PublicKey.
//
// @return nullptr if the GenericPublicKey protobuf type is not supported
//
static std::unique_ptr<CryptoOps::PublicKey> ParsePublicKey(
const GenericPublicKey& key);
private:
virtual ~PublicKeyProtoUtil() {}
// @return nullptr if the PublicKey is not supported
static std::unique_ptr<EcP256PublicKey> EncodeEcPublicKey(
const CryptoOps::PublicKey& key);
// @return nullptr if the EcP256PublicKey is invalid
static std::unique_ptr<CryptoOps::PublicKey> ParseEcPublicKey(
const EcP256PublicKey& key);
// @return nullptr if the PublicKey is not supported
static std::unique_ptr<SimpleRsaPublicKey> EncodeRsaPublicKey(
const CryptoOps::PublicKey& key);
// @return nullptr if the SimpleRsaPublicKey is invalid
static std::unique_ptr<CryptoOps::PublicKey> ParseRsaPublicKey(
const SimpleRsaPublicKey& key);
};
} // namespace securemessage
#endif // SECUREMESSAGE_PUBLIC_KEY_PROTO_UTIL_H_
@@ -1,90 +0,0 @@
/*
* 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.
*/
#ifndef SECUREMESSAGE_RAW_SECURE_MESSAGE_PARSER_H_
#define SECUREMESSAGE_RAW_SECURE_MESSAGE_PARSER_H_
#include <memory>
#include "securemessage/common.h"
#include "securemessage/crypto_ops.h"
namespace securemessage {
// Utility class to parse and verify raw byte {@link SecureMessage} protos.
// Verifies the signature on the message, and decrypts "signcrypted" messages
// (while simultaneously verifying the signature).
//
// @see RawSecureMessageBuilder
class RawSecureMessageParser {
public:
//
// Parses a raw {@link SecureMessage} that is already separated out into
// signature and headerAndBody, containing a cleartext payload body, and
// verifies the signature.
//
// @param associated_data optional associated data bound to the signature (but
// not in the message). Send an empty string when not using.
// @return a string to the raw {@link HeaderAndBody} pair (which
// is fully verified) or a nullptr on error @see
// SecureMessageBuilder#BuildSignedCleartextMessage
//
static std::unique_ptr<string> ParseSignedCleartextMessage(
const string& signature,
const string& header_and_body,
const CryptoOps::Key& verification_key,
CryptoOps::SigType sig_type,
const string& associated_data);
//
// Parses a raw {@link SecureMessage} that is already separated out into
// signature and headerAndBody, containing an encrypted payload body,
// extracting a decryption of the payload body and verifying the signature.
//
// @return a string to the the raw {@link HeaderAndBody} pair
// (which is fully verified and decrypted or a nullptr on error
// @see SecureMessageBuilder#BuildSignCryptedMessage
//
static std::unique_ptr<string> ParseSignCryptedMessage(
const string& signature,
const string& header_and_body,
const CryptoOps::Key& verification_key,
CryptoOps::SigType sig_type,
const CryptoOps::SecretKey& decryption_key,
CryptoOps::EncType enc_type,
const string& associated_data);
private:
RawSecureMessageParser(); // Do not instantiate
~RawSecureMessageParser();
//
// Verifies the components of a raw {@link HeaderAndBody}.
//
// @return true if the header_and_body can be verified.
//
static bool VerifyHeaderAndBody(
const string& signature,
const string& header_and_body,
const CryptoOps::Key& verification_key,
CryptoOps::SigType sig_type,
CryptoOps::EncType enc_type,
const string& associated_data,
bool suppress_associated_data);
};
} // namespace securemessage
#endif // SECUREMESSAGE_RAW_SECURE_MESSAGE_PARSER_H_
@@ -1,177 +0,0 @@
/*
* 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.
*/
#ifndef SECUREMESSAGE_SECURE_MESSAGE_BUILDER_H_
#define SECUREMESSAGE_SECURE_MESSAGE_BUILDER_H_
#include <memory>
#include "proto/securemessage.pb.h"
#include "securemessage/byte_buffer.h"
#include "securemessage/common.h"
#include "securemessage/crypto_ops.h"
namespace securemessage {
//
// Builder for {@link SecureMessage} protos. Can be used to create either signed
// messages, or "signcrypted" (encrypted then signed) messages that include a
// tight binding between the ciphertext portion and a verification key identity.
//
// All the language non-specific work is done from within the
// {@link RawSecureMessageBuilder} class.
//
// @see SecureMessageParser
// @see RawSecureMessageBuilder
//
class SecureMessageBuilder {
public:
SecureMessageBuilder();
virtual ~SecureMessageBuilder();
//
// Resets this {@link SecureMessageBuilder} instance to a blank configuration
// (and returns it).
//
SecureMessageBuilder* Reset();
//
// Optional metadata to be sent along with the header information in this
// {@link SecureMessage}.
// <p>
// Note that this value will be sent <em>UNENCRYPTED</em> in all cases.
// <p>
// Can be used with either cleartext or signcrypted messages, but is intended
// primarily for use with signcrypted messages.
//
SecureMessageBuilder* SetPublicMetadata(const std::string& public_metadata);
//
// The recipient of the {@link SecureMessage} should be able to uniquely
// determine the correct verification key, given only this value.
// <p>
// Can be used with either cleartext or signcrypted messages. Setting this is
// mandatory for signcrypted messages using a public key CryptoOps::SigType,
// in order to bind the encrypted body to a specific verification key.
// <p>
// Note that this value is sent <em>UNENCRYPTED</em> in all cases.
//
SecureMessageBuilder* SetVerificationKeyId(
const std::string& verification_key_id);
//
// To be used only with {@link #BuildSignCryptedMessage(CryptoOps::Key,
// CryptoOps::SigType, CryptoOps::Key, CryptoOps::EncType, string)},
// this value is sent <em>UNENCRYPTED</em> as part of the header. It should be
// used by the recipient of the {@link SecureMessage} to identify an
// appropriate key to use for decrypting the message body.
//
SecureMessageBuilder* SetDecryptionKeyId(
const std::string& decryption_key_id);
//
// Additional data is "associated" with this {@link SecureMessage}, but will
// not be sent as part of it. The recipient of the {@link SecureMessage} will
// need to provide the same data in order to verify the message body. Setting
// this to {@code null} is equivalent to using an empty array (unlike the
// behavior of {@code VerificationKeyId} and {@code DecryptionKeyId}).
// <p>
// Note that the <em>size</em> (length in bytes) of the associated data will
// be sent in the <em>UNENCRYPTED</em> header information, even if you are
// using encryption.
// <p>
// If you will be using {@link #BuildSignedCleartextMessage(CryptoOps::Key,
// CryptoOps::SigType, string)}, then anyone observing the
// {@link SecureMessage} may be able to infer this associated data via an
// "offline dictionary attack". That is, when no encryption is used, you will
// not be hiding this data simply because it is not being sent over the wire.
//
SecureMessageBuilder* SetAssociatedData(const std::string& associated_data);
//
// Generates a signed {@link SecureMessage} with the payload {@code body} left
// <em>UNENCRYPTED</em>.
// <p>
// Note that if you have used {@link #SetAssociatedData(string)}, the
// associated data will
// be subject to offline dictionary attacks if you use a public key {@link
// CryptoOps::SigType}.
// <p>
// Doesn't currently support symmetric keys stored in a TPM
// <p>
// Can return nullptr on error
//
// @see SecureMessageParser#ParseSignedCleartextMessage
//
std::unique_ptr<SecureMessage> BuildSignedCleartextMessage(
const CryptoOps::Key& signing_key, CryptoOps::SigType sig_type,
const std::string& body);
//
// Generates a signed and encrypted {@link SecureMessage}. If the signature
// type requires a public key, such as with ECDSA_P256_SHA256, then the caller
// <em>must</em> set a verification id using the
// {@link #SetVerificationKeyId(string)} method. The verification key
// id will be bound to the encrypted {@code body}, preventing attacks that
// involve stripping the signature and then re-signing the encrypted
// {@code body} as if it was originally sent by the attacker.
//
// <p> It is safe to re-use one {@link SecretKey} as both
// {@code signingKey} and {@code encryptionKey}, even if that key is also used
// for {@link #buildSignedCleartextMessage(Key, SigType, byte[])}. In fact,
// the resulting output encoding will be more compact when the same symmetric
// key is used for both.
//
// <p> Note that PublicMetadata and other header fields are left
// <em>UNENCRYPTED</em>.
//
// <p> Doesn't currently support symmetric keys stored in a TPM
//
// <p> Can return nullptr on error
//
// @param encType <em>must not</em> be set to {@link EncType#NONE}
// @see SecureMessageParser#parseSignCryptedMessage(SecureMessage,
// CryptoOps::Key, CryptoOps::SigType, CryptoOps::Key,
// CryptoOps::EncType)
//
std::unique_ptr<SecureMessage> BuildSignCryptedMessage(
const CryptoOps::Key& signing_key, CryptoOps::SigType sig_type,
const CryptoOps::SecretKey& encryption_key, CryptoOps::EncType enc_type,
const std::string& body);
private:
std::unique_ptr<ByteBuffer> public_metadata_;
std::unique_ptr<ByteBuffer> decryption_key_id_;
std::unique_ptr<ByteBuffer> verification_key_id_;
std::unique_ptr<ByteBuffer> associated_data_;
// @param iv IV or {@code null} if IV to be left unset in the Header
std::unique_ptr<Header> BuildHeader(CryptoOps::SigType sig_type,
CryptoOps::EncType enc_type,
const std::unique_ptr<std::string>& iv);
ByteBuffer SerializeHeaderAndBody(const std::string& header,
const std::string& body);
std::unique_ptr<SecureMessage> CreateSignedResult(
const CryptoOps::Key& signing_key, const CryptoOps::SigType& sig_type,
const ByteBuffer& header_and_body, const ByteBuffer& associated_data);
};
} // namespace securemessage
#endif // SECUREMESSAGE_SECURE_MESSAGE_BUILDER_H_
@@ -1,99 +0,0 @@
/*
* 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.
*/
#ifndef SECUREMESSAGE_SECURE_MESSAGE_PARSER_H_
#define SECUREMESSAGE_SECURE_MESSAGE_PARSER_H_
#include <memory>
#include "proto/securemessage.pb.h"
#include "securemessage/common.h"
#include "securemessage/crypto_ops.h"
namespace securemessage {
// This is a light wrapper on {@link RawSecureMessageParser} that binds to
// the c++ protobuf implementation.
// Utility class to parse and verify {@link SecureMessage} protos. Verifies the
// signature on the message, and decrypts "signcrypted" messages (while
// simultaneously verifying the signature).
//
// @see SecureMessageBuilder
class SecureMessageParser {
public:
// Extracts the {@link Header} component from a {@link SecureMessage} but
// <em>DOES NOT VERIFY</em> the signature when doing so. Callers should not
// trust the resulting output until after a subsequent {@code parse*()} call
// has succeeded.
//
// <p>The intention is to allow the caller to determine the type of the
// protocol message and which keys are in use, prior to attempting to verify
// (and possibly decrypt) the payload body.
//
// <p>The call will return a std::unique_ptr on success and a nullptr on error
static std::unique_ptr<Header> GetUnverifiedHeader(
const SecureMessage& secmsg);
//
// Parses a {@link SecureMessage} containing a cleartext payload body, and
// verifies the signature.
//
// @return a std::unique_ptr to the parsed {@link HeaderAndBody} pair (which
// is fully verified) or a nullptr on error @see
// SecureMessageBuilder#BuildSignedCleartextMessage
//
static std::unique_ptr<HeaderAndBody> ParseSignedCleartextMessage(
const SecureMessage& secmsg, const CryptoOps::Key& verification_key,
CryptoOps::SigType sig_type);
//
// Parses a {@link SecureMessage} containing a cleartext payload body, and
// verifies the signature.
//
// @param assocaited_data optional associated data bound to the signature (but
// not in the message). Pass an empty string when not using.
// @return a std::unique_ptr to the parsed {@link HeaderAndBody} pair (which
// is fully verified) or a nullptr on error @see
// SecureMessageBuilder#BuildSignedCleartextMessage
//
static std::unique_ptr<HeaderAndBody> ParseSignedCleartextMessage(
const SecureMessage& secmsg, const CryptoOps::Key& verification_key,
CryptoOps::SigType sig_type, const string& associated_data);
//
// Parses a {@link SecureMessage} containing an encrypted payload body,
// extracting a decryption of the payload body and verifying the signature.
//
// @param associated_data optional associated data bound to the signature
// (but not in the message). Pass an empty string when not using.
// @return a std::unique_ptr to the the parsed {@link HeaderAndBody} pair
// (which is fully verified and decrypted or a nullptr on error
// @see SecureMessageBuilder#BuildSignCryptedMessage
//
static std::unique_ptr<HeaderAndBody> ParseSignCryptedMessage(
const SecureMessage& secmsg, const CryptoOps::Key& verification_key,
CryptoOps::SigType sig_type, const CryptoOps::SecretKey& decryption_key,
CryptoOps::EncType enc_type, const string& associated_data);
private:
SecureMessageParser(); // Do not instantiate
~SecureMessageParser();
};
} // namespace securemessage
#endif // SECUREMESSAGE_SECURE_MESSAGE_PARSER_H_
@@ -1,103 +0,0 @@
/*
* 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.
*/
#ifndef SECUREMESSAGE_SECURE_MESSAGE_WRAPPER_H_
#define SECUREMESSAGE_SECURE_MESSAGE_WRAPPER_H_
#include <memory>
#include "securemessage/common.h"
#include "securemessage/crypto_ops.h"
namespace securemessage {
// Utility class to allow alternate implementations of the securemessage
// protobuf to be used (for example, an objective-c implementation).
//
// @see SecureMessage
class SecureMessageWrapper {
public:
// Takes the byte representation of the {@link HeaderAndBody} and returns
// the iv field from the {@link Header}. If this does not exist, this
// function will return nullptr.
static std::unique_ptr<string> ParseHeaderIv(
const string& header_and_body_bytes);
// Takes the byte representation of the {@link HeaderAndBody} and returns the
// byte representation of the {@link Header}. If this does not exist, this
// function will return nullptr.
static std::unique_ptr<string> ParseHeader(
const string& header_and_body_bytes);
// Takes the byte representation of the {@link HeaderAndBodyInternal} and
// returns the byte representation of the {@link Header}. If this does not
// exist, this function will return nullptr.
static std::unique_ptr<string> ParseInternalHeader(
const string& header_and_body_bytes);
// Takes the byte representation of the {@link HeaderAndBody} and returns
// the {@link Body}. If this does not exist, this function will return
// nullptr.
static std::unique_ptr<string> ParseBody(const string& header_and_body_bytes);
// Takes the byte representation of the {@link Header} and {@link Body} and
// returns the byte representation of {@link HeaderAndBody}.
static std::unique_ptr<string> BuildHeaderAndBody(
const string& header_bytes, const string& body_bytes);
// Takes the byte representation of the header and returns the int value
// for the SigScheme enum
static int GetSignatureScheme(const string& header_bytes);
// Takes the byte representation of the header and returns the int value
// for the EncScheme enum
static int GetEncryptionScheme(const string& header_bytes);
// Takes the byte representation of the header and returns the length of the
// associated data stored in the header
static uint32_t GetAssociatedDataLength(const string& header_bytes);
// Tests if the byte representation of the header has a decryption key id
static bool HasDecryptionKeyId(const string& header_bytes);
// Tests if the byte representation of the header has a verification key id
static bool HasVerificationKeyId(const string& header_bytes);
//
// Returns the constant exposed enums that are found in the
// {@link SecureMessage} protobuf.
//
// A return value of 0 would be considered an error.
//
// @see SigScheme
static int GetSigScheme(CryptoOps::SigType sig_type);
//
// Returns the constant exposed enums that are found in the
// {@link SecureMessage} protobuf.
//
// A return value of 0 would be considered an error.
//
// @see EncScheme
static int GetEncScheme(CryptoOps::EncType enc_type);
private:
SecureMessageWrapper(); // Do not instantiate
~SecureMessageWrapper();
};
} // namespace securemessage
#endif // SECUREMESSAGE_SECURE_MESSAGE_WRAPPER_H_
-60
View File
@@ -1,60 +0,0 @@
/*
* 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.
*/
#ifndef SECUREMESSAGE_UTIL_H_
#define SECUREMESSAGE_UTIL_H_
#include <memory>
#include <string>
#include "securemessage/common.h"
namespace securemessage {
class Util {
public:
//
// Makes a new std::unique_ptr<string> by taking input data and a length
//
static std::unique_ptr<std::string> MakeUniquePtrString(const void* data,
size_t length);
//
// Providing a level of indirection when logging error message. The idea
// being that this can be swapped out in platforms that log error messages in
// some more useful way.
//
static void LogError(const std::string& error_message);
//
// Provides a level of indirection for managing really bad errors. A call of
// this function indicates that an unrecoverable error happened -- perhaps
// because of an attack or a bug in an underlying crypto provider. The
// invocation of this function indicates that any subsequent behavior will be
// undefined. This level of indirection is meant to let users of this library
// figure out how they want to deal with such bad errors.
//
// This function should never return.
//
static void LogErrorAndAbort [[noreturn]] (const std::string& error_message);
private:
virtual ~Util();
};
} // namespace securemessage
#endif // SECUREMESSAGE_UTIL_H_