зеркало из https://github.com/microsoft/RIoT.git
Debug improvements + serial number (#7)
* Improved 5280 compliance + bug fixes. * Serial number checks + better info output * Ignore PEM files
This commit is contained in:
Родитель
bcd88ad20a
Коммит
3ea0968ce9
|
@ -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
|
||||
|
|
Двоичный файл не отображается.
|
@ -0,0 +1,3 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICUzCCAfqgAwIBAgIIPXSLudkxEoMwCgYIKoZIzj0EAwIwNDESMBAGA1UEAwwJUklvVCBDb3JlMQswCQYDVQQGDAJVUzERMA8GA1UECgwITVNSX1RFU1QwHhcNMTcwMTAxMDAwMDAwWhcNMzcwMTAxMDAwMDAwWjBDMSEwHwYDVQQDDBhMVjZ6OUEyY1dJR3VqSHNEMVBSdGlRPT0xCzAJBgNVBAYMAlVTMREwDwYDVQQKDAhNU1JfVEVTVDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGajjHdIVbV2PUPz3txkGqzH1DSVeZB7Uc/clZj4XJq7i8Sq6vTU3hANuHE7wyjAwHUme7z+2uALuwPq7lqLtB6jgeYwgeMwCwYDVR0PBAQDAgAEMBMGA1UdJQQMMAoGCCsGAQUFBwMCMCEGA1UdIwQaMBigFgQUJ5rnhPLv6uIGeN59l6X0PQ8MRrUwgZsGBmeBBQUEAQSBkDCBjQIBATBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOWa876ZQfrFhuVJnPLY6j6vNoT2NiwkYz93e+urv2bzaccYBfYoNNS+867QjYRvpLQQC6zPEp59dDM1kgj96x4wLQYJYIZIAWUDBAIBBCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAKBggqhkjOPQQDAgNHADBEAiBRXD1uueOWuQTT/sp/VP3NDMHpl783XcpRWtCmw7QDXwIgAhd1BzrOSgoGyq8C34oaXHIXItUJQwi0hCrv2SB0IGw=
|
||||
-----END CERTIFICATE-----
|
Двоичный файл не отображается.
|
@ -0,0 +1,3 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIPI5+EGj2UWQQFmA7Ygzdj58XV47YqyB2TwBFVMIr+pfoAoGCCqGSM49AwEHoUQDQgAEZqOMd0hVtXY9Q/Pe3GQarMfUNJV5kHtRz9yVmPhcmruLxKrq9NTeEA24cTvDKMDAdSZ7vP7a4Au7A+ruWou0Hg==
|
||||
-----END EC PRIVATE KEY-----
|
Двоичный файл не отображается.
|
@ -0,0 +1,3 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBpDCCAUqgAwIBAgIIBRLow3RIMrAwCgYIKoZIzj0EAwIwNDESMBAGA1UEAwwJUklvVCBSMDB0MQswCQYDVQQGDAJVUzERMA8GA1UECgwITVNSX1RFU1QwHhcNMTcwMTAxMDAwMDAwWhcNMzcwMTAxMDAwMDAwWjA0MRIwEAYDVQQDDAlSSW9UIENvcmUxCzAJBgNVBAYMAlVTMREwDwYDVQQKDAhNU1JfVEVTVDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOWa876ZQfrFhuVJnPLY6j6vNoT2NiwkYz93e+urv2bzaccYBfYoNNS+867QjYRvpLQQC6zPEp59dDM1kgj96x6jRjBEMAsGA1UdDwQEAwIABDASBgNVHRMBAf8ECDAGAQH/AgEBMCEGA1UdIwQaMBigFgQUXevJbkUllKHIR0hqBYXzGKbUzVAwCgYIKoZIzj0EAwIDSAAwRQIgUVw9brnjlrkE0/7Kf1T9zQzB6Ze/N13KUVrQpsO0A18CIQCaROqEcN9XyESsY4DpSTIYoNmPSHAPU9RMqsmalWREOg==
|
||||
-----END CERTIFICATE-----
|
Двоичный файл не отображается.
|
@ -0,0 +1,3 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5ZrzvplB+sWG5Umc8tjqPq82hPY2LCRjP3d766u/ZvNpxxgF9ig01L7zrtCNhG+ktBALrM8Snn10MzWSCP3rHg==
|
||||
-----END PUBLIC KEY-----
|
Двоичный файл не отображается.
|
@ -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")
|
||||
|
|
Загрузка…
Ссылка в новой задаче