[es] Add es::CertificateBody

This commit is contained in:
jakcron 2018-06-22 21:57:55 +08:00
parent c2b8223413
commit 3089069c8b
3 changed files with 344 additions and 5 deletions

View file

@ -0,0 +1,69 @@
#pragma once
#include <string>
#include <fnd/MemoryBlob.h>
#include <fnd/ISerialiseableBinary.h>
#include <es/cert.h>
namespace es
{
class CertificateBody
: public fnd::ISerialiseableBinary
{
public:
CertificateBody();
CertificateBody(const CertificateBody& other);
void operator=(const CertificateBody& other);
bool operator==(const CertificateBody& other) const;
bool operator!=(const CertificateBody& other) const;
void importBinary(byte_t* src, size_t size);
void exportBinary();
const byte_t* getBytes() const;
size_t getSize() const;
void clear();
const std::string& getIssuer() const;
void setIssuer(const std::string& issuer);
es::cert::PublicKeyType getPublicKeyType() const;
void setPublicKeyType(cert::PublicKeyType type);
const std::string& getSubject() const;
void setSubject(const std::string& subject);
uint32_t getCertId() const;
void setCertId(uint32_t id);
const crypto::rsa::sRsa4096Key& getRsa4098PublicKey() const;
void setRsa4098PublicKey(const crypto::rsa::sRsa4096Key& key);
const crypto::rsa::sRsa2048Key& getRsa2048PublicKey() const;
void setRsa2048PublicKey(const crypto::rsa::sRsa2048Key& key);
const crypto::ecdsa::sEcdsa240Point& getEcdsa240PublicKey() const;
void setEcdsa240PublicKey(const crypto::ecdsa::sEcdsa240Point& key);
private:
const std::string kModuleName = "CERTIFICATE_BODY";
// raw binary
fnd::MemoryBlob mBinaryBlob;
// variables
std::string mIssuer;
std::string mSubject;
uint32_t mCertId;
cert::PublicKeyType mPublicKeyType;
crypto::rsa::sRsa4096Key mRsa4096PublicKey;
crypto::rsa::sRsa2048Key mRsa2048PublicKey;
crypto::ecdsa::sEcdsa240Point mEcdsa240PublicKey;
// helpers
bool isEqual(const CertificateBody& other) const;
void copyFrom(const CertificateBody& other);
};
}

View file

@ -3,6 +3,7 @@
#include <fnd/types.h>
#include <crypto/aes.h>
#include <crypto/rsa.h>
#include <crypto/ecdsa.h>
namespace es
{
@ -19,31 +20,31 @@ namespace es
static const size_t kSubjectSize = 0x40;
}
#pragma pack(push,1)
struct sCertificateBody
struct sCertificateHeader
{
char issuer[cert::kIssuerSize];
be_uint32_t key_type;
char subject[cert::kSubjectSize];
be_uint32_t cert_id;
}
};
struct sRsa4096PublicKeyBlock
{
byte_t modulus[crypto::rsa::kRsa4096Size];
byte_t public_exponent[0x4];
byte_t public_exponent[crypto::rsa::kRsaPublicExponentSize];
byte_t padding[0x34];
};
struct sRsa2048PublicKeyBlock
{
byte_t modulus[crypto::rsa::kRsa2048Size];
byte_t public_exponent[0x4];
byte_t public_exponent[crypto::rsa::kRsaPublicExponentSize];
byte_t padding[0x34];
};
struct sEcdsa240PublicKeyBlock
{
byte_t public_key[0x3C];
crypto::ecdsa::sEcdsa240Point public_key;
byte_t padding[0x3C];
};
#pragma pack(pop)

View file

@ -0,0 +1,269 @@
#include <es/CertificateBody.h>
es::CertificateBody::CertificateBody()
{
clear();
}
es::CertificateBody::CertificateBody(const CertificateBody& other)
{
copyFrom(other);
}
void es::CertificateBody::operator=(const CertificateBody& other)
{
copyFrom(other);
}
bool es::CertificateBody::operator==(const CertificateBody& other) const
{
return isEqual(other);
}
bool es::CertificateBody::operator!=(const CertificateBody& other) const
{
return !(*this == other);
}
void es::CertificateBody::importBinary(byte_t* src, size_t size)
{
clear();
// check minimum size
if (size < sizeof(sCertificateHeader))
{
throw fnd::Exception(kModuleName, "Certificate too small");
}
const sCertificateHeader* hdr = (const sCertificateHeader*)src;
// get public key size
size_t pubkeySize = 0;
switch (hdr->key_type.get())
{
case (cert::RSA4096):
pubkeySize = sizeof(sRsa4096PublicKeyBlock);
break;
case (cert::RSA2048):
pubkeySize = sizeof(sRsa2048PublicKeyBlock);
break;
case (cert::ECDSA240):
pubkeySize = sizeof(sEcdsa240PublicKeyBlock);
break;
default:
throw fnd::Exception(kModuleName, "Unknown public key type");
}
// check total size
if (size < (sizeof(sCertificateHeader) + pubkeySize))
{
throw fnd::Exception(kModuleName, "Certificate too small");
}
// save raw binary
mBinaryBlob.alloc((sizeof(sCertificateHeader) + pubkeySize));
memcpy(mBinaryBlob.getBytes(), src, mBinaryBlob.getSize());
// save hdr variables
hdr = (const sCertificateHeader*)mBinaryBlob.getBytes();
if (hdr->issuer[0] != 0)
mIssuer = std::string(hdr->issuer, cert::kIssuerSize);
mPublicKeyType = (cert::PublicKeyType)hdr->key_type.get();
if (hdr->subject[0] != 0)
mSubject = std::string(hdr->subject, cert::kSubjectSize);
mCertId = hdr->cert_id.get();
// save public key
if (mPublicKeyType == cert::RSA4096)
{
const sRsa4096PublicKeyBlock* pubkey = (const sRsa4096PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader));
memcpy(mRsa4096PublicKey.modulus, pubkey->modulus, sizeof(mRsa4096PublicKey.modulus));
memcpy(mRsa4096PublicKey.public_exponent, pubkey->public_exponent, sizeof(mRsa4096PublicKey.public_exponent));
}
else if (mPublicKeyType == cert::RSA2048)
{
const sRsa2048PublicKeyBlock* pubkey = (const sRsa2048PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader));
memcpy(mRsa2048PublicKey.modulus, pubkey->modulus, sizeof(mRsa2048PublicKey.modulus));
memcpy(mRsa2048PublicKey.public_exponent, pubkey->public_exponent, sizeof(mRsa2048PublicKey.public_exponent));
}
else if (mPublicKeyType == cert::ECDSA240)
{
const sEcdsa240PublicKeyBlock* pubkey = (const sEcdsa240PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader));
mEcdsa240PublicKey = pubkey->public_key;
}
}
void es::CertificateBody::exportBinary()
{
// get public key size
size_t pubkeySize = 0;
switch (mPublicKeyType)
{
case (cert::RSA4096):
pubkeySize = sizeof(sRsa4096PublicKeyBlock);
break;
case (cert::RSA2048):
pubkeySize = sizeof(sRsa2048PublicKeyBlock);
break;
case (cert::ECDSA240):
pubkeySize = sizeof(sEcdsa240PublicKeyBlock);
break;
default:
throw fnd::Exception(kModuleName, "Unknown public key type");
}
mBinaryBlob.alloc(sizeof(sCertificateHeader) + pubkeySize);
sCertificateHeader* hdr = (sCertificateHeader*)mBinaryBlob.getBytes();
// copy header vars
strncpy(hdr->issuer, mIssuer.c_str(), cert::kIssuerSize);
hdr->key_type = mPublicKeyType;
strncpy(hdr->subject, mSubject.c_str(), cert::kSubjectSize);
hdr->cert_id = mCertId;
// copy public key
if (mPublicKeyType == cert::RSA4096)
{
sRsa4096PublicKeyBlock* pubkey = (sRsa4096PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader));
memcpy(pubkey->modulus, mRsa4096PublicKey.modulus, sizeof(mRsa4096PublicKey.modulus));
memcpy(pubkey->public_exponent, mRsa4096PublicKey.public_exponent, sizeof(mRsa4096PublicKey.public_exponent));
}
else if (mPublicKeyType == cert::RSA2048)
{
sRsa2048PublicKeyBlock* pubkey = (sRsa2048PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader));
memcpy(pubkey->modulus, mRsa2048PublicKey.modulus, sizeof(mRsa2048PublicKey.modulus));
memcpy(pubkey->public_exponent, mRsa2048PublicKey.public_exponent, sizeof(mRsa2048PublicKey.public_exponent));
}
else if (mPublicKeyType == cert::ECDSA240)
{
sEcdsa240PublicKeyBlock* pubkey = (sEcdsa240PublicKeyBlock*)(mBinaryBlob.getBytes() + sizeof(sCertificateHeader));
pubkey->public_key = mEcdsa240PublicKey;
}
}
const byte_t* es::CertificateBody::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t es::CertificateBody::getSize() const
{
return mBinaryBlob.getSize();
}
void es::CertificateBody::clear()
{
mIssuer.clear();
mSubject.clear();
mCertId = 0;
mPublicKeyType = cert::RSA2048;
memset(&mRsa4096PublicKey, 0, sizeof(crypto::rsa::sRsa4096Key));
memset(&mRsa2048PublicKey, 0, sizeof(crypto::rsa::sRsa2048Key));
memset(&mEcdsa240PublicKey, 0, sizeof(crypto::ecdsa::sEcdsa240Point));
}
const std::string& es::CertificateBody::getIssuer() const
{
return mIssuer;
}
void es::CertificateBody::setIssuer(const std::string& issuer)
{
if (issuer.size() > cert::kIssuerSize)
{
throw fnd::Exception(kModuleName, "Issuer name too long");
}
mIssuer = issuer;
}
es::cert::PublicKeyType es::CertificateBody::getPublicKeyType() const
{
return mPublicKeyType;
}
void es::CertificateBody::setPublicKeyType(cert::PublicKeyType type)
{
mPublicKeyType = type;
}
const std::string& es::CertificateBody::getSubject() const
{
return mSubject;
}
void es::CertificateBody::setSubject(const std::string& subject)
{
if (subject.size() > cert::kSubjectSize)
{
throw fnd::Exception(kModuleName, "Subject name too long");
}
mSubject = subject;
}
uint32_t es::CertificateBody::getCertId() const
{
return mCertId;
}
void es::CertificateBody::setCertId(uint32_t id)
{
mCertId = id;
}
const crypto::rsa::sRsa4096Key& es::CertificateBody::getRsa4098PublicKey() const
{
return mRsa4096PublicKey;
}
void es::CertificateBody::setRsa4098PublicKey(const crypto::rsa::sRsa4096Key& key)
{
mRsa4096PublicKey = key;
}
const crypto::rsa::sRsa2048Key& es::CertificateBody::getRsa2048PublicKey() const
{
return mRsa2048PublicKey;
}
void es::CertificateBody::setRsa2048PublicKey(const crypto::rsa::sRsa2048Key& key)
{
mRsa2048PublicKey = key;
}
const crypto::ecdsa::sEcdsa240Point& es::CertificateBody::getEcdsa240PublicKey() const
{
return mEcdsa240PublicKey;
}
void es::CertificateBody::setEcdsa240PublicKey(const crypto::ecdsa::sEcdsa240Point& key)
{
mEcdsa240PublicKey = key;
}
bool es::CertificateBody::isEqual(const CertificateBody& other) const
{
return (mIssuer == other.mIssuer) \
&& (mSubject == other.mSubject) \
&& (mCertId == other.mCertId) \
&& (mPublicKeyType == other.mPublicKeyType) \
&& (mRsa4096PublicKey == other.mRsa4096PublicKey) \
&& (mRsa2048PublicKey == other.mRsa2048PublicKey) \
&& (mEcdsa240PublicKey == other.mEcdsa240PublicKey);
}
void es::CertificateBody::copyFrom(const CertificateBody& other)
{
mBinaryBlob = other.mBinaryBlob;
mIssuer = other.mIssuer;
mSubject = other.mSubject;
mCertId = other.mCertId;
mPublicKeyType = other.mPublicKeyType;
mRsa4096PublicKey = other.mRsa4096PublicKey;
mRsa2048PublicKey = other.mRsa2048PublicKey;
mEcdsa240PublicKey = other.mEcdsa240PublicKey;
}