A simple library to support serving https.

Dependents:   oldheating gps motorhome heating

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