Debug improvements + serial number (#7)

* Improved 5280 compliance + bug fixes.

* Serial number checks + better info output

* Ignore PEM files
This commit is contained in:
Paul England 2018-03-19 11:12:22 -07:00 коммит произвёл Dennis Mattoon
Родитель bcd88ad20a
Коммит 3ea0968ce9
26 изменённых файлов: 540 добавлений и 46 удалений

4
.gitignore поставляемый
Просмотреть файл

@ -1,6 +1,10 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# DICE test tools
*.pem
# User-specific files
*.suo
*.user

Двоичные данные
Emulator/AliasCert.der Normal file

Двоичный файл не отображается.

3
Emulator/AliasCert.pem Normal file
Просмотреть файл

@ -0,0 +1,3 @@
-----BEGIN CERTIFICATE-----
MIICUzCCAfqgAwIBAgIIPXSLudkxEoMwCgYIKoZIzj0EAwIwNDESMBAGA1UEAwwJUklvVCBDb3JlMQswCQYDVQQGDAJVUzERMA8GA1UECgwITVNSX1RFU1QwHhcNMTcwMTAxMDAwMDAwWhcNMzcwMTAxMDAwMDAwWjBDMSEwHwYDVQQDDBhMVjZ6OUEyY1dJR3VqSHNEMVBSdGlRPT0xCzAJBgNVBAYMAlVTMREwDwYDVQQKDAhNU1JfVEVTVDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGajjHdIVbV2PUPz3txkGqzH1DSVeZB7Uc/clZj4XJq7i8Sq6vTU3hANuHE7wyjAwHUme7z+2uALuwPq7lqLtB6jgeYwgeMwCwYDVR0PBAQDAgAEMBMGA1UdJQQMMAoGCCsGAQUFBwMCMCEGA1UdIwQaMBigFgQUJ5rnhPLv6uIGeN59l6X0PQ8MRrUwgZsGBmeBBQUEAQSBkDCBjQIBATBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOWa876ZQfrFhuVJnPLY6j6vNoT2NiwkYz93e+urv2bzaccYBfYoNNS+867QjYRvpLQQC6zPEp59dDM1kgj96x4wLQYJYIZIAWUDBAIBBCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAKBggqhkjOPQQDAgNHADBEAiBRXD1uueOWuQTT/sp/VP3NDMHpl783XcpRWtCmw7QDXwIgAhd1BzrOSgoGyq8C34oaXHIXItUJQwi0hCrv2SB0IGw=
-----END CERTIFICATE-----

Двоичные данные
Emulator/AliasKey.der Normal file

Двоичный файл не отображается.

3
Emulator/AliasKey.pem Normal file
Просмотреть файл

@ -0,0 +1,3 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIPI5+EGj2UWQQFmA7Ygzdj58XV47YqyB2TwBFVMIr+pfoAoGCCqGSM49AwEHoUQDQgAEZqOMd0hVtXY9Q/Pe3GQarMfUNJV5kHtRz9yVmPhcmruLxKrq9NTeEA24cTvDKMDAdSZ7vP7a4Au7A+ruWou0Hg==
-----END EC PRIVATE KEY-----

Двоичные данные
Emulator/DeviceIDCrt.der Normal file

Двоичный файл не отображается.

3
Emulator/DeviceIDCrt.pem Normal file
Просмотреть файл

@ -0,0 +1,3 @@
-----BEGIN CERTIFICATE-----
MIIBpDCCAUqgAwIBAgIIBRLow3RIMrAwCgYIKoZIzj0EAwIwNDESMBAGA1UEAwwJUklvVCBSMDB0MQswCQYDVQQGDAJVUzERMA8GA1UECgwITVNSX1RFU1QwHhcNMTcwMTAxMDAwMDAwWhcNMzcwMTAxMDAwMDAwWjA0MRIwEAYDVQQDDAlSSW9UIENvcmUxCzAJBgNVBAYMAlVTMREwDwYDVQQKDAhNU1JfVEVTVDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOWa876ZQfrFhuVJnPLY6j6vNoT2NiwkYz93e+urv2bzaccYBfYoNNS+867QjYRvpLQQC6zPEp59dDM1kgj96x6jRjBEMAsGA1UdDwQEAwIABDASBgNVHRMBAf8ECDAGAQH/AgEBMCEGA1UdIwQaMBigFgQUXevJbkUllKHIR0hqBYXzGKbUzVAwCgYIKoZIzj0EAwIDSAAwRQIgUVw9brnjlrkE0/7Kf1T9zQzB6Ze/N13KUVrQpsO0A18CIQCaROqEcN9XyESsY4DpSTIYoNmPSHAPU9RMqsmalWREOg==
-----END CERTIFICATE-----

Двоичные данные
Emulator/DeviceIDPublic.der Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5ZrzvplB+sWG5Umc8tjqPq82hPY2LCRjP3d766u/ZvNpxxgF9ig01L7zrtCNhG+ktBALrM8Snn10MzWSCP3rHg==
-----END PUBLIC KEY-----

Двоичные данные
Emulator/R00tCrt.der Normal file

Двоичный файл не отображается.

3
Emulator/R00tCrt.pem Normal file
Просмотреть файл

@ -0,0 +1,3 @@
-----BEGIN CERTIFICATE-----
MIIBgTCCASegAwIBAgIIGis8TV4AAAAwCgYIKoZIzj0EAwIwNDESMBAGA1UEAwwJUklvVCBSMDB0MQswCQYDVQQGDAJVUzERMA8GA1UECgwITVNSX1RFU1QwHhcNMTcwMTAxMDAwMDAwWhcNMzcwMTAxMDAwMDAwWjA0MRIwEAYDVQQDDAlSSW9UIFIwMHQxCzAJBgNVBAYMAlVTMREwDwYDVQQKDAhNU1JfVEVTVDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGmrWiahUg/J7F2llfSXSLn+0j0JxZ0fp1DTlEnI/Jzr3x5bsP2eRppj0jflBPvU+qJwT7EFnq2a1Tz4OWKxzn2jIzAhMAsGA1UdDwQEAwIABDASBgNVHRMBAf8ECDAGAQH/AgECMAoGCCqGSM49BAMCA0gAMEUCIFFcPW6545a5BNP+yn9U/c0MwemXvzddylFa0KbDtANfAiEA6T3h6/YLI4NcqiGjWIVCbAuUqQb3YS1lpJ63qVbBFsw=
-----END CERTIFICATE-----

Просмотреть файл

@ -0,0 +1,183 @@
/*
* sha1.c
*
* Originally witten by Steve Reid <steve@edmweb.com>
*
* Modified by Aaron D. Gifford <agifford@infowest.com>
*
* NO COPYRIGHT - THIS IS 100% IN THE PUBLIC DOMAIN
*
* The original unmodified version is available at:
* ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
//
// 24-JAN-2018; RIoT adaptation (Paul England;MSFT).
//
#include <string.h>
#include "RiotSha1.h"
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#if (QCC_TARGET_ENDIAN == QCC_LITTLE_ENDIAN)
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&(sha1_quadbyte)0xFF00FF00) \
|(rol(block->l[i],8)&(sha1_quadbyte)0x00FF00FF))
#else
#define blk0(i) block->l[i]
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
typedef union _BYTE64QUAD16 {
sha1_byte c[64];
sha1_quadbyte l[16];
} BYTE64QUAD16;
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1_Transform(sha1_quadbyte state[5], sha1_byte buffer[64]) {
sha1_quadbyte a, b, c, d, e;
BYTE64QUAD16 *block;
block = (BYTE64QUAD16*)buffer;
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a, b, c, d, e, 0); R0(e, a, b, c, d, 1); R0(d, e, a, b, c, 2); R0(c, d, e, a, b, 3);
R0(b, c, d, e, a, 4); R0(a, b, c, d, e, 5); R0(e, a, b, c, d, 6); R0(d, e, a, b, c, 7);
R0(c, d, e, a, b, 8); R0(b, c, d, e, a, 9); R0(a, b, c, d, e, 10); R0(e, a, b, c, d, 11);
R0(d, e, a, b, c, 12); R0(c, d, e, a, b, 13); R0(b, c, d, e, a, 14); R0(a, b, c, d, e, 15);
R1(e, a, b, c, d, 16); R1(d, e, a, b, c, 17); R1(c, d, e, a, b, 18); R1(b, c, d, e, a, 19);
R2(a, b, c, d, e, 20); R2(e, a, b, c, d, 21); R2(d, e, a, b, c, 22); R2(c, d, e, a, b, 23);
R2(b, c, d, e, a, 24); R2(a, b, c, d, e, 25); R2(e, a, b, c, d, 26); R2(d, e, a, b, c, 27);
R2(c, d, e, a, b, 28); R2(b, c, d, e, a, 29); R2(a, b, c, d, e, 30); R2(e, a, b, c, d, 31);
R2(d, e, a, b, c, 32); R2(c, d, e, a, b, 33); R2(b, c, d, e, a, 34); R2(a, b, c, d, e, 35);
R2(e, a, b, c, d, 36); R2(d, e, a, b, c, 37); R2(c, d, e, a, b, 38); R2(b, c, d, e, a, 39);
R3(a, b, c, d, e, 40); R3(e, a, b, c, d, 41); R3(d, e, a, b, c, 42); R3(c, d, e, a, b, 43);
R3(b, c, d, e, a, 44); R3(a, b, c, d, e, 45); R3(e, a, b, c, d, 46); R3(d, e, a, b, c, 47);
R3(c, d, e, a, b, 48); R3(b, c, d, e, a, 49); R3(a, b, c, d, e, 50); R3(e, a, b, c, d, 51);
R3(d, e, a, b, c, 52); R3(c, d, e, a, b, 53); R3(b, c, d, e, a, 54); R3(a, b, c, d, e, 55);
R3(e, a, b, c, d, 56); R3(d, e, a, b, c, 57); R3(c, d, e, a, b, 58); R3(b, c, d, e, a, 59);
R4(a, b, c, d, e, 60); R4(e, a, b, c, d, 61); R4(d, e, a, b, c, 62); R4(c, d, e, a, b, 63);
R4(b, c, d, e, a, 64); R4(a, b, c, d, e, 65); R4(e, a, b, c, d, 66); R4(d, e, a, b, c, 67);
R4(c, d, e, a, b, 68); R4(b, c, d, e, a, 69); R4(a, b, c, d, e, 70); R4(e, a, b, c, d, 71);
R4(d, e, a, b, c, 72); R4(c, d, e, a, b, 73); R4(b, c, d, e, a, 74); R4(a, b, c, d, e, 75);
R4(e, a, b, c, d, 76); R4(d, e, a, b, c, 77); R4(c, d, e, a, b, 78); R4(b, c, d, e, a, 79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
}
/* SHA1_Init - Initialize new context */
void SHA1_Init(SHA_CTX* context) {
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void SHA1_Update(SHA_CTX *context, sha1_byte *data, unsigned int len) {
unsigned int i, j;
j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
context->count[1] += (len >> 29);
if ((j + len) > 63) {
/* Fill buffer, which may have data from a previous update. */
memcpy(&context->buffer[j], data, (i = 64 - j));
SHA1_Transform(context->state, context->buffer);
/* Transform full blocks */
j = 0;
for (; i + 63 < len; i += 64) {
memcpy(&context->buffer[j], &data[i], 64);
SHA1_Transform(context->state, context->buffer);
}
}
else i = 0;
/* Not enough bytes to fill a block. Keep for next update */
memcpy(&context->buffer[j], &data[i], len - i);
}
void* SHA1_force_memset(void* s, int v, size_t n) {
volatile unsigned char* p = (volatile unsigned char*)s;
while (n--) *p++ = (unsigned char) v;
return s;
}
/* Add padding and return the message digest. */
void SHA1_Final(sha1_byte digest[SHA1_DIGEST_LENGTH], SHA_CTX *context) {
sha1_quadbyte i, j;
sha1_byte finalcount[8];
for (i = 0; i < 8; i++) {
finalcount[i] = (sha1_byte)((context->count[(i >= 4 ? 0 : 1)]
>> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */
}
SHA1_Update(context, (sha1_byte *)"\200", 1);
while ((context->count[0] & 504) != 448) {
SHA1_Update(context, (sha1_byte *)"\0", 1);
}
/* Should cause a SHA1_Transform() */
SHA1_Update(context, finalcount, 8);
for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
digest[i] = (sha1_byte)
((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
}
/* Wipe variables */
SHA1_force_memset(&i, 0, sizeof(i));
SHA1_force_memset(&j, 0, sizeof(j));
SHA1_force_memset(context->buffer, 0, SHA1_BLOCK_LENGTH);
SHA1_force_memset(context->state, 0, SHA1_DIGEST_LENGTH);
SHA1_force_memset(context->count, 0, 8);
SHA1_force_memset(&finalcount, 0, 8);
}
void RIOT_SHA1_Block(const uint8_t *buf, size_t bufSize, uint8_t *digest)
{
SHA_CTX context;
SHA1_Init(&context);
SHA1_Update(&context, (uint8_t*) buf, (unsigned int) bufSize);
SHA1_Final(digest, &context);
}

Просмотреть файл

@ -20,6 +20,7 @@ static int ecPublicKeyOID[] = { 1,2,840,10045, 2,1,-1 };
static int prime256v1OID[] = { 1,2,840,10045, 3,1,7,-1 };
static int keyUsageOID[] = { 2,5,29,15,-1 };
static int extKeyUsageOID[] = { 2,5,29,37,-1 };
static int extAuthKeyIdentifierOID[] = { 2,5,29,35,-1 };
static int subjectAltNameOID[] = { 2,5,29,17,-1 };
static int clientAuthOID[] = { 1,3,6,1,5,5,7,3,2,-1 };
static int sha256OID[] = { 2,16,840,1,101,3,4,2,1,-1 };
@ -28,6 +29,25 @@ static int countryNameOID[] = { 2,5,4,6,-1 };
static int orgNameOID[] = { 2,5,4,10,-1 };
static int basicConstraintsOID[] = { 2,5,29,19,-1 };
/*
Notes for Dennis.
Check RIotSha1.h/c these are new. I tried to make changes similar to what you did
for Sha256, but please scrub.
*/
static int GenerateGuidFromSeed(char* nameBuf, uint32_t *nameBufLen, const uint8_t* seed, size_t seedLen)
{
uint8_t digest[RIOT_DIGEST_LENGTH];
int result;
RIOT_SHA256_Block(seed, seedLen, digest);
result = Base64Encode(digest, 16, nameBuf, nameBufLen);
return result;
}
static int
X509AddExtensions(
DERBuilderContext *Tbs,
@ -36,11 +56,27 @@ X509AddExtensions(
uint8_t *Fwid,
uint32_t FwidLen
)
// Create the RIoT extensions. The RIoT subject altName + extended key usage.
// Create the RIoT extensions.
{
CHK(DERStartExplicit(Tbs, 3));
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERStartSequenceOrSet(Tbs, true));
uint8_t authKeyIdentifier[SHA1_DIGEST_LENGTH];
RIOT_SHA1_Block(DevIdPub, DevIdPubLen, authKeyIdentifier);
uint8_t keyUsage = RIOT_X509_KEY_USAGE;
uint8_t extLen = 1;
CHK(DERStartExplicit(Tbs, 3));
CHK( DERStartSequenceOrSet(Tbs, true));
// keyUsage
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERAddOID(Tbs, keyUsageOID));
CHK( DERStartEnvelopingOctetString(Tbs));
CHK( DERAddBitString(Tbs, &keyUsage, extLen));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
// extendedKeyUsage
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERAddOID(Tbs, extKeyUsageOID));
CHK( DERStartEnvelopingOctetString(Tbs));
CHK( DERStartSequenceOrSet(Tbs, true));
@ -48,6 +84,20 @@ X509AddExtensions(
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
// authKeyIdentifier
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERAddOID(Tbs, extAuthKeyIdentifierOID));
CHK( DERStartEnvelopingOctetString(Tbs));
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERStartExplicit(Tbs, 0));
CHK( DERAddOctetString(Tbs, authKeyIdentifier, 20));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
// RIoT extension
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERAddOID(Tbs, riotOID));
CHK( DERStartEnvelopingOctetString(Tbs));
@ -67,6 +117,7 @@ X509AddExtensions(
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK(DERPopNesting(Tbs));
@ -115,12 +166,21 @@ int
X509GetDeviceCertTBS(
DERBuilderContext *Tbs,
RIOT_X509_TBS_DATA *TbsData,
RIOT_ECC_PUBLIC *DevIdKeyPub
)
RIOT_ECC_PUBLIC *DevIdKeyPub,
uint8_t *RootKeyPub,
uint32_t RootKeyPubLen)
{
uint8_t encBuffer[65];
uint8_t encBuffer[65];
uint32_t encBufferLen;
uint8_t keyUsage = RIOT_X509_KEY_USAGE;
uint8_t authKeyIdentifier[SHA1_DIGEST_LENGTH];
RiotCrypt_ExportEccPub(DevIdKeyPub, encBuffer, &encBufferLen);
if (RootKeyPub != NULL)
{
RIOT_SHA1_Block(RootKeyPub, RootKeyPubLen, authKeyIdentifier);
}
CHK(DERStartSequenceOrSet(Tbs, true));
CHK( DERAddShortExplicitInteger(Tbs, 2));
@ -139,19 +199,20 @@ X509GetDeviceCertTBS(
CHK( DERAddOID(Tbs, ecPublicKeyOID));
CHK( DERAddOID(Tbs, prime256v1OID));
CHK( DERPopNesting(Tbs));
RiotCrypt_ExportEccPub(DevIdKeyPub, encBuffer, &encBufferLen);
CHK( DERAddBitString(Tbs, encBuffer, encBufferLen));
CHK( DERPopNesting(Tbs));
CHK( DERStartExplicit(Tbs, 3));
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERAddOID(Tbs, keyUsageOID));
CHK( DERStartEnvelopingOctetString(Tbs));
encBufferLen = 1;
CHK( DERAddBitString(Tbs, &keyUsage, encBufferLen)); // Actually 6bits
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERAddOID(Tbs, basicConstraintsOID));
CHK( DERAddBoolean(Tbs, true));
CHK( DERStartEnvelopingOctetString(Tbs));
@ -161,7 +222,21 @@ X509GetDeviceCertTBS(
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
if(RootKeyPub!=NULL)
{
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERAddOID(Tbs, extAuthKeyIdentifierOID));
CHK( DERStartEnvelopingOctetString(Tbs));
CHK( DERStartSequenceOrSet(Tbs, true));
CHK( DERStartExplicit(Tbs, 0));
CHK( DERAddOctetString(Tbs, authKeyIdentifier, 20));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
}
CHK( DERPopNesting(Tbs));
CHK( DERPopNesting(Tbs));
CHK(DERPopNesting(Tbs));
@ -215,9 +290,26 @@ X509GetAliasCertTBS(
uint32_t FwidLen
)
{
uint8_t encBuffer[65];
int result;
char guidBuffer[64];
uint8_t encBuffer[65];
uint32_t encBufferLen;
if (strcmp(TbsData->SubjectCommon, "*") == 0)
{
RiotCrypt_ExportEccPub(DevIdKeyPub, encBuffer, &encBufferLen);
uint32_t bufLen = sizeof(guidBuffer);
// replace the common-name with a per-device GUID (derived from the DeviceID
// public key
result = GenerateGuidFromSeed(guidBuffer, &bufLen, encBuffer, encBufferLen);
if (result < 0) return result;
guidBuffer[bufLen-1] = 0;
TbsData->SubjectCommon = guidBuffer;
}
CHK(DERStartSequenceOrSet(Tbs, true));
CHK( DERAddShortExplicitInteger(Tbs, 2));
CHK( DERAddIntegerFromArray(Tbs, TbsData->SerialNum, RIOT_X509_SNUM_LEN));
@ -493,4 +585,5 @@ X509MakeRootCert(
Error:
return -1;
}
}

Просмотреть файл

@ -26,6 +26,7 @@ Confidential Information
#include <stdint.h>
#include <stdbool.h>
#include "RiotSha1.h"
#include "RiotSha256.h"
#include "RiotAes128.h"
#include "RiotHmac.h"

Просмотреть файл

@ -0,0 +1,100 @@
#pragma once
/*
* sha.h
*
* Originally taken from the public domain SHA1 implementation
* written by by Steve Reid <steve@edmweb.com>
*
* Modified by Aaron D. Gifford <agifford@infowest.com>
*
* NO COPYRIGHT - THIS IS 100% IN THE PUBLIC DOMAIN
*
* The original unmodified version is available at:
* ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
//
// 24-JAN-2018; RIoT adaptation (Paul England;MSFT).
//
#ifndef __RIOT_CRYPTO_SHA1_H__
#define __RIOT_CRYPTO_SHA1_H__
#include "RiotTarget.h"
typedef int asb;
typedef uint8_t sha2_uint8_t; // Exactly 1 byte
typedef uint32_t sha2_word32; // Exactly 4 bytes
typedef uint64_t sha2_word64; // Exactly 8 bytes
#define SHA1_DIGEST_LENGTH 20
#ifdef __cplusplus
extern "C" {
#endif
/* Make sure you define these types for your architecture: */
typedef unsigned int sha1_quadbyte; /* 4 byte type */
typedef unsigned char sha1_byte; /* single byte type */
/*
* Be sure to get the above definitions right. For instance, on my
* x86 based FreeBSD box, I define LITTLE_ENDIAN and use the type
* "unsigned long" for the quadbyte. On FreeBSD on the Alpha, however,
* while I still use LITTLE_ENDIAN, I must define the quadbyte type
* as "unsigned int" instead.
*/
#define SHA1_BLOCK_LENGTH 64
#define SHA1_DIGEST_LENGTH 20
/* The SHA1 structure: */
typedef struct _SHA_CTX {
sha1_quadbyte state[5];
sha1_quadbyte count[2];
sha1_byte buffer[SHA1_BLOCK_LENGTH];
} SHA_CTX;
void* SHA1_force_memset(void* s, int v, size_t n);
#ifndef NOPROTO
void SHA1_Init(SHA_CTX *context);
void SHA1_Update(SHA_CTX *context, sha1_byte *data, unsigned int len);
void SHA1_Final(sha1_byte digest[SHA1_DIGEST_LENGTH], SHA_CTX* context);
#else
void SHA1_Init();
void SHA1_Update();
void SHA1_Final();
#endif
//
// Hash a block of data
// @param buf the buffer containing the data to hash
// @param bufSize the number of bytes in the buffer
// @param digest the buffer to hold the digest. Must be of size SHA1_DIGEST_LENGTH
//
void RIOT_SHA1_Block(const uint8_t *buf, size_t bufSize,
uint8_t *digest);
#ifdef __cplusplus
}
#endif
#endif

Просмотреть файл

@ -7,7 +7,7 @@
extern "C" {
#endif
#define RIOT_X509_SNUM_LEN 0x05
#define RIOT_X509_SNUM_LEN 0x08
// KeyUsage :: = BIT STRING{
// digitalSignature(0),
@ -38,7 +38,9 @@ int
X509GetDeviceCertTBS(
DERBuilderContext *Tbs,
RIOT_X509_TBS_DATA *TbsData,
RIOT_ECC_PUBLIC *DevIdKeyPub
RIOT_ECC_PUBLIC *DevIdKeyPub,
uint8_t *RootKeyPub,
uint32_t RootKeyPubLen
);
int

Просмотреть файл

@ -41,11 +41,15 @@ uint8_t rDigest[DICE_DIGEST_LENGTH] = {
// just pick a reasonable minimum buffer size and worry about this later.
#define REASONABLE_MIN_CERT_SIZE DER_MAX_TBS
// The static data fields that make up the Alias Cert "to be signed" region
// The static data fields that make up the Alias Cert "to be signed" region.
// Note: if the device SubjectCommon is *, then a device-unique GUID is
// generated
// Note2: if a self-signed DeviceID cert is selected, then the tbs-data
// subject is also used for the issuer
RIOT_X509_TBS_DATA x509AliasTBSData = { { 0x0A, 0x0B, 0x0C, 0x0D, 0x0E },
"RIoT Core", "MSR_TEST", "US",
"170101000000Z", "370101000000Z",
"RIoT Device", "MSR_TEST", "US" };
"*", "MSR_TEST", "US" };
// The static data fields that make up the DeviceID Cert "to be signed" region
RIOT_X509_TBS_DATA x509DeviceTBSData = { { 0x0E, 0x0D, 0x0C, 0x0B, 0x0A },
@ -59,11 +63,14 @@ RIOT_X509_TBS_DATA x509RootTBSData = { { 0x1A, 0x2B, 0x3C, 0x4D, 0x5E },
"170101000000Z", "370101000000Z",
"RIoT R00t", "MSR_TEST", "US" };
// Selectors for DeviceID cert handling (See comment below)
// Selectors for DeviceID cert handling.
#define RIOT_ROOT_SIGNED 0x00
#define RIOT_SELF_SIGNED 0x01
#define RIOT_CSR 0x02
#define DEVICE_ID_CERT_TYPE RIOT_ROOT_SIGNED
// The "root" signing key. This is intended for development purposes only.
// This key is used to sign the DeviceID certificate, the certificiate for
// this "root" key represents the "trusted" CA for the developer-mode DPS
@ -83,6 +90,10 @@ BYTE eccRootPrivBytes[sizeof(ecc_privatekey)] = {
0x53, 0xf1, 0x56, 0x15, 0x02, 0xf0, 0x71, 0xc0, 0x53, 0x49, 0xc8, 0xda,
0xe6, 0x26, 0xa9, 0x0b, 0x17, 0x88, 0xe5, 0x70, 0x00, 0x00, 0x00, 0x00 };
// Sets tbsData->SerialNumber to a quasi-random value derived from seedData
void SetSerialNumber(RIOT_X509_TBS_DATA* tbsData, const uint8_t* seedData, size_t seedLen);
int
CreateDeviceAuthBundle(
BYTE *Seed,
@ -125,7 +136,7 @@ main()
CreateDeviceAuthBundle(UDS, DICE_UDS_LENGTH,
FWID, RIOT_DIGEST_LENGTH,
deviceIDPub, &deviceIDPubSize,
devCert, &devCertSize, RIOT_ROOT_SIGNED,
devCert, &devCertSize, DEVICE_ID_CERT_TYPE,
aliasKey, &aliaskeySize,
aliasCert, &aliasCertSize);
@ -185,6 +196,9 @@ CreateDeviceAuthBundle(
(const uint8_t *)RIOT_LABEL_IDENTITY,
lblSize(RIOT_LABEL_IDENTITY));
// Set the serial number
SetSerialNumber(&x509DeviceTBSData, digest, RIOT_DIGEST_LENGTH);
// Combine CDI and FWID, result in digest
RiotCrypt_Hash2(digest, RIOT_DIGEST_LENGTH,
digest, RIOT_DIGEST_LENGTH,
@ -197,6 +211,9 @@ CreateDeviceAuthBundle(
(const uint8_t *)RIOT_LABEL_ALIAS,
lblSize(RIOT_LABEL_ALIAS));
// Set the serial number
SetSerialNumber(&x509AliasTBSData, digest, RIOT_DIGEST_LENGTH);
// Copy DeviceID Public
length = sizeof(PEM);
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
@ -222,6 +239,7 @@ CreateDeviceAuthBundle(
*AliasKeyEncodedSize = length;
memcpy(AliasKeyEncoded, PEM, length);
#ifdef DEBUG
printf("Alias Key");
PrintHex(derCtx.Buffer, derCtx.Position);
@ -243,12 +261,12 @@ CreateDeviceAuthBundle(
// Generate Alias Key Certificate
X509MakeAliasCert(&derCtx, &tbsSig);
// Copy Alias Key Certificate
length = sizeof(PEM);
DERtoPEM(&derCtx, CERT_TYPE, PEM, &length);
*AliasCertBufSize = length;
memcpy(AliasCertBuffer, PEM, length);
#ifdef DEBUG
printf("Alias Cert");
PrintHex(derCtx.Buffer, derCtx.Position);
@ -267,8 +285,13 @@ CreateDeviceAuthBundle(
if (DeviceCertType == RIOT_SELF_SIGNED) {
// Generating self-signed DeviceID certificate
x509DeviceTBSData.IssuerCommon = x509DeviceTBSData.SubjectCommon;
x509DeviceTBSData.IssuerOrg = x509DeviceTBSData.IssuerOrg;
x509DeviceTBSData.IssuerCountry = x509DeviceTBSData.SubjectCountry;
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
X509GetDeviceCertTBS(&derCtx, &x509DeviceTBSData, &deviceIDPub);
X509GetDeviceCertTBS(&derCtx, &x509DeviceTBSData, &deviceIDPub, NULL, 0);
// Sign the DeviceID Certificate's TBS region
RiotCrypt_Sign(&tbsSig, derCtx.Buffer, derCtx.Position, &deviceIDPriv);
@ -289,8 +312,13 @@ CreateDeviceAuthBundle(
}
else {
// Generating "root"-signed DeviceID certificate
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
X509GetDeviceCertTBS(&derCtx, &x509DeviceTBSData, &deviceIDPub);
uint8_t rootPubBuffer[65];
uint32_t rootPubBufLen = 65;
RiotCrypt_ExportEccPub((RIOT_ECC_PUBLIC *)eccRootPubBytes, rootPubBuffer, &rootPubBufLen);
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
X509GetDeviceCertTBS(&derCtx, &x509DeviceTBSData, &deviceIDPub, rootPubBuffer, rootPubBufLen);
// Sign the DeviceID Certificate's TBS region
RiotCrypt_Sign(&tbsSig, derCtx.Buffer, derCtx.Position, (RIOT_ECC_PRIVATE *)eccRootPrivBytes);
@ -301,9 +329,16 @@ CreateDeviceAuthBundle(
X509MakeDeviceCert(&derCtx, &tbsSig);
}
// Copy DeviceID Certificate or CSR
// Copy DeviceID Certificate or CSR Note: depending on DeviceCertType this
// may be self-signed, Root-signed, or a CSR
uint32_t pemType = CERT_TYPE;
if (DeviceCertType == RIOT_CSR)
{
pemType = CERT_REQ_TYPE;
}
length = sizeof(PEM);
DERtoPEM(&derCtx, CERT_TYPE, PEM, &length);
DERtoPEM(&derCtx, pemType, PEM, &length);
*DeviceCertBufSize = length;
memcpy(DeviceCertBuffer, PEM, length);
@ -321,7 +356,7 @@ CreateDeviceAuthBundle(
X509GetRootCertTBS(&derCtx, &x509RootTBSData, (RIOT_ECC_PUBLIC*)eccRootPubBytes);
// Self-sign the "root" Certificate's TBS region
RiotCrypt_Sign(&tbsSig, derCtx.Buffer, derCtx.Position, &deviceIDPriv);
RiotCrypt_Sign(&tbsSig, derCtx.Buffer, derCtx.Position, (RIOT_ECC_PRIVATE *)eccRootPrivBytes);
// Generate "root" CA cert
X509MakeRootCert(&derCtx, &tbsSig);
@ -342,6 +377,24 @@ CreateDeviceAuthBundle(
return 0;
}
void SetSerialNumber(RIOT_X509_TBS_DATA* tbsData, const uint8_t* seedData, size_t seedLen)
{
// Set the tbsData serial number to 8 bytes of data derived from seedData
uint8_t hashBuf[DICE_DIGEST_LENGTH];
// SHA-1 hash of "DICE SEED" == 6e785006 84941d8f 7880520c 60b8c7e4 3f1a3c00
uint8_t seedExtender[20] = { 0x6e, 0x78, 0x50, 0x06, 0x84, 0x94, 0x1d, 0x8f, 0x78,
0x80, 0x52, 0x0c, 0x60, 0xb8, 0xc7, 0xe4, 0x3f, 0x1a, 0x3c, 0x00 };
DiceSHA256_2(seedData, seedLen, seedExtender, sizeof(seedExtender), hashBuf);
// Take first 8 bytes to form serial number
memcpy(tbsData->SerialNum, hashBuf, RIOT_X509_SNUM_LEN);
// DER encoded serial number must be positive and the first byte must not be zero
tbsData->SerialNum[0] &= (uint8_t)0x7f;
tbsData->SerialNum[0] |= (uint8_t)0x01;
return;
}
#ifdef DEBUG
void HexConvert(uint8_t* in, int inLen, char* outBuf, int outLen)
{

Просмотреть файл

@ -166,6 +166,7 @@
<ClInclude Include="RIoT\RIoTCrypt\include\RiotEcc.h" />
<ClInclude Include="RIoT\RIoTCrypt\include\RiotHmac.h" />
<ClInclude Include="RIoT\RIoTCrypt\include\RiotKdf.h" />
<ClInclude Include="RIoT\RIoTCrypt\include\RiotSha1.h" />
<ClInclude Include="RIoT\RIoTCrypt\include\RiotSha256.h" />
<ClInclude Include="RIoT\RIoTCrypt\include\RiotTarget.h" />
<ClInclude Include="RIoT\RIoTCrypt\include\RiotX509Bldr.h" />
@ -184,6 +185,7 @@
<ClCompile Include="RIoT\RIoTCrypt\RiotEcc.c" />
<ClCompile Include="RIoT\RIoTCrypt\RiotHmac.c" />
<ClCompile Include="RIoT\RIoTCrypt\RiotKdf.c" />
<ClCompile Include="RIoT\RIoTCrypt\RiotSha1.c" />
<ClCompile Include="RIoT\RIoTCrypt\RiotSha256.c" />
<ClCompile Include="RIoT\RIoTCrypt\RiotX509Bldr.c" />
<ClCompile Include="stdafx.cpp" />

Просмотреть файл

@ -36,6 +36,9 @@
<ClCompile Include="RIoT\RIoTCrypt\RiotBase64.c">
<Filter>RIoT\RIoTCrypt</Filter>
</ClCompile>
<ClCompile Include="RIoT\RIoTCrypt\RiotSha1.c">
<Filter>RIoT\RIoTCrypt</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="DICE\DiceSha256.h">
@ -79,6 +82,9 @@
<ClInclude Include="RIoT\RIoTCrypt\include\RiotBase64.h">
<Filter>RIoT\RIoTCrypt\Headers</Filter>
</ClInclude>
<ClInclude Include="RIoT\RIoTCrypt\include\RiotSha1.h">
<Filter>RIoT\RIoTCrypt\Headers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="RIoT">

Просмотреть файл

@ -22,5 +22,3 @@ Soon we will also share demos and sample code for specific DICE-enabled hardware
For more information on DICE, and to learn how you can contribute, we encourage you to check out the [DICE Architectures workgroup](https://trustedcomputinggroup.org/work-groups/dice-architectures/) (DiceArch) in the [Trusted Computing Group](https://trustedcomputinggroup.org/). For questions, comments, or contributions to the RIoT project from MSR, feel free to contact us at riotdev@microsoft.com.

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -22,32 +22,32 @@
<ProjectGuid>{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>DICE</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -15,18 +15,19 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>Loader</RootNamespace>
<ProjectName>FW</ProjectName>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -14,18 +14,19 @@
<ProjectGuid>{B7AF6C41-115E-4926-A8B3-7842FFE9D605}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>RIoT</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

Просмотреть файл

@ -5,10 +5,12 @@
namespace DICETest
{
using System;
using System.Linq;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Extension;
@ -199,6 +201,7 @@ namespace DICETest
internal bool CheckSubjectIssuerLinkage()
{
bool ok = true;
Notify($"Checking Subject/Issuer Linkage");
foreach (var c in Certs)
{
Notify($" {c.SubjectDN.ToString()}");
@ -217,6 +220,10 @@ namespace DICETest
ok = false;
}
}
if(ok)
{
NotifySuccess("OK");
}
return ok;
}
@ -226,6 +233,8 @@ namespace DICETest
/// <returns>Chain signing linkage is OK</returns>
internal bool CheckSigningLinkage()
{
Notify($"Checking signature chains");
bool ok = true;
// alias to cert-before-root should be signed by parent
for (int j = 0; j < NumCerts - 1; j++)
@ -239,7 +248,7 @@ namespace DICETest
}
catch(Exception e)
{
Error($"Cert {target.SubjectDN.ToString()} is not properly signed by {signer.SubjectDN.ToString()}. Error is {e.ToString()}");
Error($" Cert {target.SubjectDN.ToString()} is not properly signed by {signer.SubjectDN.ToString()}. Error is {e.ToString()}");
ok = false;
}
}
@ -250,11 +259,15 @@ namespace DICETest
{
root.Verify(rootPubKey);
}
catch (Exception e)
catch (Exception)
{
Error($"Root cert is not properly self-signed. Error is {e.ToString()}");
Error($"Root cert is not properly self-signed.");
ok = false;
}
if(ok)
{
NotifySuccess("OK");
}
return ok;
}
@ -447,7 +460,12 @@ namespace DICETest
try
{
var keyUsage= c.GetKeyUsage();
if(keyUsage.Length>9)
if(keyUsage==null)
{
Error($"KeyUsage is missing.");
return false;
}
if (keyUsage.Length>9)
{
Error($"Unsupported KeyUsage. This usually means that DecipherOnly is asserted, which is an error");
return false;
@ -550,13 +568,21 @@ namespace DICETest
/// <returns></returns>
bool CheckSerialNumber(X509Certificate c)
{
var sn = c.SerialNumber;
int snNumBytes = sn.ToByteArray().Length;
BigInteger sn = c.SerialNumber;
var snBytes = sn.ToByteArray();
int snNumBytes = snBytes.Length;
if(snNumBytes<serialNumMinBytes)
{
Error($"Serial number is only {snNumBytes} bytes, but {serialNumMinBytes} is recommended");
return false;
}
int numZeroBytes = snBytes.Count(x => x == 0);
if (numZeroBytes>=3)
{
Warning($"Serial number has {numZeroBytes} zeros. Is it random?");
return false;
}
return true;
}

Просмотреть файл

@ -18,6 +18,12 @@ namespace DICETest
{
// Usage:
// -option c0 c1 c2...
// Examples:
// -chain AliasCert.PEM DeviceIDCrt.PEM R00tCrt.PEM
// -chain AliasCert.PEM DeviceIDCrt.PEM
// -csr DeviceIDCrt.PEM
if (args.Length == 0 || args[1] == "?")
{
PrintHelp();
@ -43,6 +49,7 @@ namespace DICETest
{
Program.Print("One or more errors in certificate chain.", NotifyType.Error);
}
else
{
Program.Print("Certificates and certificate chain are valid.", NotifyType.Success);
}

Просмотреть файл

@ -67,6 +67,8 @@ namespace RIoT
bool ok = ParseParms(args);
if (!ok) return;
string workingDir = Environment.CurrentDirectory;
foreach(var action in ActiveParms)
{
if (action.Flag == "dir")