supercop

Basic CLI for supercop
git clone git://git.finwo.net/app/supercop
Log | Files | Refs | README | LICENSE

encode.c (1910B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 #include "common.h"
      6 #include "armor.h"
      7 #include "b64.h"
      8 
      9 #ifdef __cplusplus
     10 extern "C" {
     11 #endif
     12 
     13 // Wrap raw bytes in an ascii-armor block; returns malloc'd NUL-terminated text.
     14 static char *asc_wrap(const char *label, const unsigned char *raw, size_t rawlen,
     15                       size_t *outlen) {
     16   char *b64, *out;
     17   size_t b64len, need;
     18   int n;
     19 
     20   b64 = asc_b64_encode(raw, rawlen, &b64len);
     21   if (!b64) return NULL;
     22   // "-----BEGIN %s-----\n" + b64 + "-----END %s-----\n" + NUL
     23   need = strlen("-----BEGIN -----\n-----END -----\n") + 2 * strlen(label) + b64len + 1;
     24   out = malloc(need);
     25   if (!out) {
     26     free(b64);
     27     return NULL;
     28   }
     29   n = snprintf(out, need, "-----BEGIN %s-----\n%s-----END %s-----\n",
     30                label, b64, label);
     31   free(b64);
     32   if (n < 0 || (size_t)n >= need) {
     33     free(out);
     34     return NULL;
     35   }
     36   *outlen = (size_t)n;
     37   return out;
     38 }
     39 
     40 char * fmt_asc_encode(struct KeyPair *kp, size_t *len) {
     41   char *priv = NULL, *pub = NULL, *out;
     42   size_t privlen = 0, publen = 0;
     43 
     44   if (!kp || !kp->public_key || !len) return NULL;
     45   // Armor carries just the key bytes, no prefix. A full pair emits both a
     46   // PRIVATE block (64 private bytes) and a PUBLIC block (32 public bytes);
     47   // a pub-only pair emits just the PUBLIC block.
     48   if (kp->private_key) {
     49     priv = asc_wrap(ASC_LABEL_PRIVATE, kp->private_key, 64, &privlen);
     50     if (!priv) return NULL;
     51   }
     52   pub = asc_wrap(ASC_LABEL_PUBLIC, kp->public_key, 32, &publen);
     53   if (!pub) {
     54     if (priv) free(priv);
     55     return NULL;
     56   }
     57   out = malloc(privlen + publen + 1);
     58   if (!out) {
     59     if (priv) free(priv);
     60     if (pub) free(pub);
     61     return NULL;
     62   }
     63   memcpy(out, priv, privlen);
     64   memcpy(out + privlen, pub, publen);
     65   out[privlen + publen] = '\0';
     66   free(priv);
     67   free(pub);
     68   *len = privlen + publen;
     69   return out;
     70 }
     71 
     72 #ifdef __cplusplus
     73 } // extern "C"
     74 #endif