A simple library to support serving https.
Dependents: oldheating gps motorhome heating
pki/pri-key.c
- Committer:
- andrewboyson
- Date:
- 2019-07-25
- Revision:
- 0:be515c9019e3
- Child:
- 1:9c66a551a67e
File content as of revision 0:be515c9019e3:
#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; }