Skip to content

[CM-22] Authority Key Identifier support #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 28, 2018
Merged
Show file tree
Hide file tree
Changes from 2 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
6 changes: 6 additions & 0 deletions src/ArduinoCloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ int ArduinoCloudClass::begin(Client& net)
ECCX08Cert.setIssuerOrganizationalUnitName("IT");
ECCX08Cert.setIssuerCommonName("Arduino");

const byte authorityKeyIdentifier[20] = {
0xb2, 0xed, 0xef, 0xed, 0x3b, 0xbf, 0xc7, 0x71, 0x75, 0x24, 0x33, 0xd1, 0xae, 0x8b, 0x54, 0xed, 0x97, 0x14, 0x7a, 0x1d
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattiabertorello I've hardcoded the value in the lib. for now.

Will this value be constant?

Copy link
Contributor

@mattiabertorello mattiabertorello Jul 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value of the authorityKeyIdentifier must be saved in the crypto chip and initialized during the provisioning sketch, so it can change because you can sign the csr with different ca.
For example we will have a CA for dev and another CA for prod

But to support the actual flow during the provisioning sketch if the authorityKeyIdentifier field is empty, no error should be throw.

Thanks

A tip
If you put the issue key in the pull request you will link the PR with the issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made changes in
b264428 to persist this value in the crypto chip and prompt for in during provisioning sketch.

ECCX08Cert.setAuthorityKeyIdentifier(authorityKeyIdentifier);

if (!ECCX08Cert.endReconstruction()) {
return 0;
}
Expand Down
72 changes: 66 additions & 6 deletions src/utility/ECCX08Cert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ ECCX08CertClass::ECCX08CertClass() :
_keySlot(-1),
_compressedCertSlot(-1),
_serialNumberSlot(-1),
_authorityKeyIdentifier(NULL),
_bytes(NULL),
_length(0)
{
Expand Down Expand Up @@ -334,10 +335,19 @@ int ECCX08CertClass::endReconstruction()

int publicKeyLen = publicKeyLength();

int authorityKeyIdentifierLen = authorityKeyIdentifierLength(_authorityKeyIdentifier);

int signatureLen = signatureLength(compressedCert.signature);

int certInfoLen = 5 + serialNumberLen + 12 + issuerHeaderLen + issuerLen + 32 +
subjectHeaderLen + subjectLen + publicKeyLen + 4;
subjectHeaderLen + subjectLen + publicKeyLen;

if (authorityKeyIdentifierLen) {
certInfoLen += authorityKeyIdentifierLen;
} else {
certInfoLen += 4;
}

int certInfoHeaderLen = sequenceHeaderLength(certInfoLen);

int certDataLen = certInfoLen + certInfoHeaderLen + signatureLen;
Expand Down Expand Up @@ -411,11 +421,16 @@ int ECCX08CertClass::endReconstruction()
appendPublicKey(publicKey, out);
out += publicKeyLen;

// null sequence
*out++ = 0xA3;
*out++ = 0x02;
*out++ = 0x30;
*out++ = 0x00;
if (authorityKeyIdentifierLen) {
appendAuthorityKeyIdentifier(_authorityKeyIdentifier, out);
out += authorityKeyIdentifierLen;
} else {
// null sequence
*out++ = 0xA3;
*out++ = 0x02;
*out++ = 0x30;
*out++ = 0x00;
}

// signature
appendSignature(compressedCert.signature, out);
Expand Down Expand Up @@ -494,6 +509,11 @@ void ECCX08CertClass::setSubjectCommonName(const String& commonName)
_subjectCommonName = commonName;
}

void ECCX08CertClass::setAuthorityKeyIdentifier(const byte authorityKeyIdentifier[])
{
_authorityKeyIdentifier = authorityKeyIdentifier;
}

int ECCX08CertClass::versionLength()
{
return 3;
Expand Down Expand Up @@ -546,6 +566,11 @@ int ECCX08CertClass::publicKeyLength()
return (2 + 2 + 9 + 10 + 4 + 64);
}

int ECCX08CertClass::authorityKeyIdentifierLength(const byte authorityKeyIdentifier[])
{
return (authorityKeyIdentifier == NULL) ? 0 : 37;
}

int ECCX08CertClass::signatureLength(const byte signature[])
{
const byte* r = &signature[0];
Expand Down Expand Up @@ -684,6 +709,41 @@ void ECCX08CertClass::appendPublicKey(const byte publicKey[], byte out[])
memcpy(out, publicKey, 64);
}

void ECCX08CertClass::appendAuthorityKeyIdentifier(const byte authorityKeyIdentifier[], byte out[])
{
// [3]
*out++ = 0xa3;
*out++ = 0x23;

// sequence
*out++ = ASN1_SEQUENCE;
*out++ = 0x21;

// sequence
*out++ = ASN1_SEQUENCE;
*out++ = 0x1f;

// 2.5.29.35 authorityKeyIdentifier(X.509 extension)
*out++ = 0x06;
*out++ = 0x03;
*out++ = 0x55;
*out++ = 0x1d;
*out++ = 0x23;

// octet string
*out++ = 0x04;
*out++ = 0x18;

// sequence
*out++ = ASN1_SEQUENCE;
*out++ = 0x16;

*out++ = 0x80;
*out++ = 0x14;

memcpy(out, authorityKeyIdentifier, 20);
}

void ECCX08CertClass::appendSignature(const byte signature[], byte out[])
{
// signature algorithm
Expand Down
8 changes: 8 additions & 0 deletions src/utility/ECCX08Cert.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class ECCX08CertClass {
void setSubjectOrganizationalUnitName(const String& organizationalUnitName);
void setSubjectCommonName(const String& commonName);

void setAuthorityKeyIdentifier(const byte authorityKeyIdentifier[]);

private:
int versionLength();

Expand All @@ -54,6 +56,8 @@ class ECCX08CertClass {

int publicKeyLength();

int authorityKeyIdentifierLength(const byte authorityKeyIdentifier[]);

int signatureLength(const byte signature[]);

int serialNumberLength(const byte serialNumber[]);
Expand All @@ -72,6 +76,8 @@ class ECCX08CertClass {

void appendPublicKey(const byte publicKey[], byte out[]);

void appendAuthorityKeyIdentifier(const byte authorityKeyIdentifier[], byte out[]);

void appendSignature(const byte signature[], byte out[]);

void appendSerialNumber(const byte serialNumber[], byte out[]);
Expand Down Expand Up @@ -103,6 +109,8 @@ class ECCX08CertClass {
String _subjectOrganizationalUnitName;
String _subjectCommonName;

const byte* _authorityKeyIdentifier;

byte _temp[88];
byte* _bytes;
int _length;
Expand Down