A simple library to support serving https.
Dependents: oldheating gps motorhome heating
Diff: pki/pri-key.c
- Revision:
- 0:be515c9019e3
- Child:
- 1:9c66a551a67e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pki/pri-key.c Thu Jul 25 21:16:24 2019 +0000 @@ -0,0 +1,128 @@ +#include "base64.h" +#include "log.h" +#include "bignum.h" + +/* +RSAPrivateKey ::= SEQUENCE { + version INTEGER, + modulus INTEGER, -- n + publicExponent INTEGER, -- e + privateExponent INTEGER, -- d + prime1 INTEGER, -- p + prime2 INTEGER, -- q + exponent1 INTEGER, -- d mod (p-1) + exponent2 INTEGER, -- d mod (q-1) + coefficient INTEGER, -- (inverse of q) mod p + otherPrimeInfos OtherPrimeInfos OPTIONAL +*/ + +char v [ 4]; //version +char n [128]; //modulus +char e [ 4]; //publicExponent +char d [128]; //privateExponent +char p [ 64]; //prime1 +char q [ 64]; //prime2 +char dp [ 64]; //exponent1 -- d mod (p-1) +char dq [ 64]; //exponent2 -- d mod (q-1) +char invq[ 64]; //coefficient -- (inverse of q) mod p + +static const char* pNext; +static const char* buffer = +#include "pri-key.inc" +; +static char readChar() +{ + char c = *pNext; + if (!c) return 0; + pNext++; + return c; +} +static int readLength() +{ + int c = Base64ReadByte(); + if (c == -1) return -1; //EOF or an error + if (c < 0x80) return c; //Single byte length + if (c == 0x80) return -1; //indefinite form - do not use + int numberOfBytes = c - 0x80; + int len = 0; + for (int i = 0; i < numberOfBytes; i++) + { + len <<= 8; + c = Base64ReadByte(); + if (c == -1) return -1; //EOF or an error + len |= c; + } + return len; +} +static int readSequence() +{ + int c = Base64ReadByte(); + if (c == -1) return -1; //EOF or an error + if (c != 0x30) return -1; //Not SEQUENCE type + int len = readLength(); + return len; +} +static int readData(char* data, int size) //Reads the data from big-endian 'pem' format into little-endian 'bn' format +{ + int c = Base64ReadByte(); + if (c == -1) return -1; //EOF or an error + if (c != 0x02) return -1; //Not INTEGER type + int pemLength = readLength(); + if (pemLength == -1) return -1; //EOF or an error + + int finalLength = pemLength; + for (int i = 0; i < pemLength; i++) + { + c = Base64ReadByte(); + if (c == -1) return -1; //EOF or an error + if (!i && !c) //Don't add if this is the msb and that byte is zero but reduce the final length by 1 + { + finalLength--; + } + else + { + data[pemLength - 1 - i] = c; //If pemLength is one too big then 'i' will also be one too big so the result is correct + } + } + for (int i = finalLength; i < size; i++) data[i] = 0; + + return finalLength + 1; +} +void PriKeyInit() +{ + pNext = buffer; + Base64ReadNextCharFunctionPointer = readChar; + + int r = 0; + r = Base64SkipLine(); if (r < 0) return; + r = readSequence(); if (r < 0) return; + + r = readData( v, sizeof( v)); if (r < 0) return; + r = readData( n, sizeof( n)); if (r < 0) return; + r = readData( e, sizeof( e)); if (r < 0) return; + r = readData( d, sizeof( d)); if (r < 0) return; + r = readData( p, sizeof( p)); if (r < 0) return; + r = readData( q, sizeof( q)); if (r < 0) return; + r = readData( dp, sizeof( dp)); if (r < 0) return; + r = readData( dq, sizeof( dq)); if (r < 0) return; + r = readData(invq, sizeof(invq)); if (r < 0) return; + + Log("Primary key content\r\n"); + LogBytesAsHex( v, sizeof( v)); Log("\n\n"); + LogBytesAsHex( n, sizeof( n)); Log("\n\n"); + LogBytesAsHex( e, sizeof( e)); Log("\n\n"); + LogBytesAsHex( d, sizeof( d)); Log("\n\n"); + LogBytesAsHex( p, sizeof( p)); Log("\n\n"); + LogBytesAsHex( q, sizeof( q)); Log("\n\n"); + LogBytesAsHex( dp, sizeof( dp)); Log("\n\n"); + LogBytesAsHex( dq, sizeof( dq)); Log("\n\n"); + LogBytesAsHex(invq, sizeof(invq)); Log("\n\n"); +} +void PriKeyDecryptStart(char* message, char* result) +{ + BnExpModStart((uint32_t*)message, (uint32_t*)d, (uint32_t*)n, (uint32_t*)result); +} +bool PriKeyDecryptFinished() +{ + return BnExpModStatus == BIGNUM_CALC_FINISHED; +} \ No newline at end of file