Annotation of rsaref/rdemo/rdemo.c, revision 1.1.1.1

1.1       root        1: /* RDEMO.C - RSAREF demonstration program
                      2:  */
                      3: 
                      4: /* Copyright (C) 1991-2 RSA Laboratories, a division of RSA Data
                      5:    Security, Inc. All rights reserved.
                      6:  */
                      7: 
                      8: #include <stdio.h>
                      9: #include <string.h>
                     10: #include "global.h"
                     11: #include "rsaref.h"
                     12: 
                     13: int main PROTO_LIST ((int, char **));
                     14: static int SetOptions PROTO_LIST ((int, char **));
                     15: static void InitRandomStruct PROTO_LIST ((R_RANDOM_STRUCT *));
                     16: static void DoSignFile PROTO_LIST ((void));
                     17: static void DoSealFile PROTO_LIST ((R_RANDOM_STRUCT *));
                     18: static void DoVerifyFile PROTO_LIST ((void));
                     19: static void DoOpenFile PROTO_LIST ((void));
                     20: static void DoGenerateKeys PROTO_LIST ((R_RANDOM_STRUCT *));
                     21: static void WriteKeypair3 PROTO_LIST ((void));
                     22: static void WriteBigInteger PROTO_LIST
                     23:   ((FILE *, unsigned char *, unsigned int));
                     24: static int ReadBlock PROTO_LIST
                     25:   ((unsigned char *, unsigned int *, unsigned int, char *));
                     26: static int ReadText PROTO_LIST
                     27:   ((unsigned char *, unsigned int *, unsigned int, char *));
                     28: static int WriteBlock PROTO_LIST ((unsigned char *, unsigned int, char *));
                     29: static int GetPublicKey PROTO_LIST ((R_RSA_PUBLIC_KEY **, char *));
                     30: static int GetPrivateKey PROTO_LIST ((R_RSA_PRIVATE_KEY **, char *));
                     31: static void PrintMessage PROTO_LIST ((char *));
                     32: static void PrintError PROTO_LIST ((char *, int));
                     33: static void GetCommand PROTO_LIST ((char *, unsigned int, char *));
                     34: 
                     35: static int SILENT_PROMPT = 0;
                     36: static int DIGEST_ALGORITHM = DA_MD5;
                     37: 
                     38: static R_RSA_PUBLIC_KEY PUBLIC_KEY1 = {
                     39:   512,
                     40:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     41:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     42:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     43:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     44:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     45:    0x00, 0x00, 0x00, 0x00, 0xc0, 0x76, 0x47, 0x97, 0xb8, 0xbe, 0xc8, 0x97,
                     46:    0x2a, 0x0e, 0xd8, 0xc9, 0x0a, 0x8c, 0x33, 0x4d, 0xd0, 0x49, 0xad, 0xd0,
                     47:    0x22, 0x2c, 0x09, 0xd2, 0x0b, 0xe0, 0xa7, 0x9e, 0x33, 0x89, 0x10, 0xbc,
                     48:    0xae, 0x42, 0x20, 0x60, 0x90, 0x6a, 0xe0, 0x22, 0x1d, 0xe3, 0xf3, 0xfc,
                     49:    0x74, 0x7c, 0xcf, 0x98, 0xae, 0xcc, 0x85, 0xd6, 0xed, 0xc5, 0x2d, 0x93,
                     50:    0xd5, 0xb7, 0x39, 0x67, 0x76, 0x16, 0x05, 0x25},
                     51:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     52:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     53:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     54:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     55:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     56:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     57:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     58:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     59:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     60:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     61:    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01}
                     62: };
                     63: 
                     64: static R_RSA_PRIVATE_KEY PRIVATE_KEY1 = {
                     65:   512,
                     66:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     67:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     68:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     69:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     70:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     71:    0x00, 0x00, 0x00, 0x00, 0xc0, 0x76, 0x47, 0x97, 0xb8, 0xbe, 0xc8, 0x97,
                     72:    0x2a, 0x0e, 0xd8, 0xc9, 0x0a, 0x8c, 0x33, 0x4d, 0xd0, 0x49, 0xad, 0xd0,
                     73:    0x22, 0x2c, 0x09, 0xd2, 0x0b, 0xe0, 0xa7, 0x9e, 0x33, 0x89, 0x10, 0xbc,
                     74:    0xae, 0x42, 0x20, 0x60, 0x90, 0x6a, 0xe0, 0x22, 0x1d, 0xe3, 0xf3, 0xfc,
                     75:    0x74, 0x7c, 0xcf, 0x98, 0xae, 0xcc, 0x85, 0xd6, 0xed, 0xc5, 0x2d, 0x93,
                     76:    0xd5, 0xb7, 0x39, 0x67, 0x76, 0x16, 0x05, 0x25},
                     77:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     78:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     79:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     80:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     81:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     82:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     83:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     84:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     85:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     86:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     87:    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01},
                     88:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     89:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     90:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     91:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     92:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     93:    0x00, 0x00, 0x00, 0x00, 0x1a, 0xe3, 0x6b, 0x75, 0x22, 0xf6, 0x64, 0x87,
                     94:    0xd9, 0xf4, 0x61, 0x0d, 0x15, 0x50, 0x29, 0x0a, 0xc2, 0x02, 0xc9, 0x29,
                     95:    0xbe, 0xdc, 0x70, 0x32, 0xcc, 0x3e, 0x02, 0xac, 0xf3, 0x7e, 0x3e, 0xbc,
                     96:    0x1f, 0x86, 0x6e, 0xe7, 0xef, 0x7a, 0x08, 0x68, 0xd2, 0x3a, 0xe2, 0xb1,
                     97:    0x84, 0xc1, 0xab, 0xd6, 0xd4, 0xdb, 0x8e, 0xa9, 0xbe, 0xc0, 0x46, 0xbd,
                     98:    0x82, 0x80, 0x37, 0x27, 0xf2, 0x88, 0x87, 0x01},
                     99:   {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    100:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    101:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0x02, 0xb6, 0x15,
                    102:     0xfe, 0x15, 0x92, 0x8f, 0x41, 0xb0, 0x2b, 0x58, 0x6b, 0x51, 0xc2, 0xc0,
                    103:     0x22, 0x60, 0xca, 0x39, 0x68, 0x18, 0xca, 0x4c, 0xba, 0x60, 0xbb, 0x89,
                    104:     0x24, 0x65, 0xbe, 0x35},
                    105:    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    106:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    107:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xee, 0xb6, 0x0d,
                    108:     0x54, 0x35, 0x18, 0xb4, 0xac, 0x74, 0x83, 0x4a, 0x05, 0x46, 0xc5, 0x07,
                    109:     0xf2, 0xe9, 0x1e, 0x38, 0x9a, 0x87, 0xe2, 0xf2, 0xbe, 0xcc, 0x6f, 0x8c,
                    110:     0x67, 0xd1, 0xc9, 0x31}},
                    111:   {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    112:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    113:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x48, 0x7e, 0x99,
                    114:     0xe3, 0x75, 0xc3, 0x8d, 0x73, 0x21, 0x12, 0xd9, 0x7d, 0x6d, 0xe8, 0x68,
                    115:     0x7f, 0xda, 0xfc, 0x5b, 0x6b, 0x5f, 0xb1, 0x6e, 0x72, 0x97, 0xd3, 0xbd,
                    116:     0x1e, 0x43, 0x55, 0x99},
                    117:    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    118:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    119:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xb5, 0x50, 0xde,
                    120:     0x64, 0x37, 0x77, 0x4d, 0xb0, 0x57, 0x77, 0x18, 0xed, 0x6c, 0x77, 0x07,
                    121:     0x24, 0xee, 0xe4, 0x66, 0xb4, 0x31, 0x14, 0xb5, 0xb6, 0x9c, 0x43, 0x59,
                    122:     0x1d, 0x31, 0x32, 0x81}},
                    123:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    124:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    125:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x4c, 0x79, 0xc4,
                    126:    0xb9, 0xbe, 0xa9, 0x7c, 0x25, 0xe5, 0x63, 0xc9, 0x40, 0x7a, 0x2d, 0x09,
                    127:    0xb5, 0x73, 0x58, 0xaf, 0xe0, 0x9a, 0xf6, 0x7d, 0x71, 0xf8, 0x19, 0x8c,
                    128:    0xb7, 0xc9, 0x56, 0xb8}
                    129: };
                    130: 
                    131: static R_RSA_PUBLIC_KEY PUBLIC_KEY2 = {
                    132:   512,
                    133:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    134:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    135:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    136:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    137:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    138:    0x00, 0x00, 0x00, 0x00, 0xe5, 0xf2, 0x0d, 0xce, 0x83, 0x32, 0x30, 0xe4,
                    139:    0x51, 0xd5, 0x0c, 0x79, 0xa5, 0x34, 0x23, 0xfb, 0x5f, 0xfb, 0xa0, 0xff,
                    140:    0x5c, 0x77, 0x96, 0xa9, 0x2c, 0x35, 0xee, 0x53, 0x02, 0xb7, 0x89, 0x2d,
                    141:    0xf0, 0x78, 0x49, 0xdd, 0xdc, 0x27, 0x79, 0x8b, 0x69, 0xa2, 0x5e, 0x7a,
                    142:    0x40, 0x27, 0x43, 0x82, 0x7a, 0xc4, 0xfa, 0x50, 0x21, 0x1f, 0x15, 0x35,
                    143:    0xc3, 0x93, 0x46, 0x62, 0xcd, 0xd4, 0x26, 0x89},
                    144:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    145:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    146:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    147:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    148:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    149:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    150:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    151:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    152:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    153:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    154:    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01}
                    155: };
                    156: 
                    157: static R_RSA_PRIVATE_KEY PRIVATE_KEY2 = {
                    158:   512,
                    159:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    160:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    161:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    162:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    163:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    164:    0x00, 0x00, 0x00, 0x00, 0xe5, 0xf2, 0x0d, 0xce, 0x83, 0x32, 0x30, 0xe4,
                    165:    0x51, 0xd5, 0x0c, 0x79, 0xa5, 0x34, 0x23, 0xfb, 0x5f, 0xfb, 0xa0, 0xff,
                    166:    0x5c, 0x77, 0x96, 0xa9, 0x2c, 0x35, 0xee, 0x53, 0x02, 0xb7, 0x89, 0x2d,
                    167:    0xf0, 0x78, 0x49, 0xdd, 0xdc, 0x27, 0x79, 0x8b, 0x69, 0xa2, 0x5e, 0x7a,
                    168:    0x40, 0x27, 0x43, 0x82, 0x7a, 0xc4, 0xfa, 0x50, 0x21, 0x1f, 0x15, 0x35,
                    169:    0xc3, 0x93, 0x46, 0x62, 0xcd, 0xd4, 0x26, 0x89},
                    170:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    171:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    172:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    173:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    174:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    175:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    176:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    177:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    178:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    179:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    180:    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01},
                    181:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    182:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    183:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    184:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    185:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    186:    0x00, 0x00, 0x00, 0x00, 0x8e, 0x6b, 0x48, 0x4f, 0xe3, 0x04, 0x60, 0x31,
                    187:    0xd9, 0xd9, 0x59, 0xdb, 0xb2, 0x0d, 0xc4, 0x47, 0x7a, 0x60, 0x70, 0x8c,
                    188:    0x19, 0x2a, 0x5c, 0x9f, 0x35, 0x29, 0xc6, 0x0d, 0x95, 0xfe, 0x35, 0x30,
                    189:    0x99, 0x54, 0xda, 0x99, 0x90, 0xe3, 0x3e, 0x1d, 0xdb, 0x32, 0x7b, 0x1d,
                    190:    0x26, 0xf2, 0x9a, 0xab, 0x03, 0x09, 0x77, 0xba, 0x4f, 0x43, 0xdb, 0xda,
                    191:    0xc8, 0x1f, 0x12, 0xd6, 0xf2, 0x57, 0x1a, 0x31},
                    192:   {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    193:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    194:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x6c, 0x5d, 0xb7,
                    195:     0x7b, 0xa7, 0x9e, 0x2f, 0x4a, 0x26, 0xec, 0xe0, 0x1b, 0x2a, 0x5f, 0x42,
                    196:     0x04, 0x87, 0xb4, 0xc4, 0x68, 0x80, 0xf3, 0x09, 0xe5, 0x48, 0x00, 0x30,
                    197:     0x6f, 0x54, 0x04, 0x75},
                    198:    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    199:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    200:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xd6, 0x25, 0x08,
                    201:     0xe5, 0x54, 0x19, 0xa3, 0x98, 0x9d, 0x77, 0x92, 0x18, 0xba, 0x9c, 0x00,
                    202:     0xda, 0x69, 0xee, 0x84, 0xf9, 0x10, 0xe5, 0xda, 0xf0, 0x7d, 0x78, 0x6c,
                    203:     0x92, 0xd8, 0xc7, 0x45}},
                    204:   {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    205:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    206:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x03, 0x32, 0x71,
                    207:     0x69, 0x3c, 0x85, 0xca, 0x20, 0xca, 0x0b, 0x22, 0xb2, 0xc2, 0x03, 0x00,
                    208:     0xce, 0x20, 0x3c, 0xf4, 0xa5, 0x93, 0x4f, 0xe2, 0x1f, 0xf7, 0x07, 0x5c,
                    209:     0x64, 0xc8, 0x24, 0x21},
                    210:    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    211:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    212:     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0xf1, 0xde, 0x01,
                    213:     0x07, 0xe9, 0x1b, 0xfa, 0x7e, 0x51, 0x6b, 0x62, 0xb2, 0x29, 0x6b, 0xb6,
                    214:     0x0f, 0xeb, 0xd5, 0xf8, 0x08, 0xc1, 0x7c, 0x90, 0xd6, 0x3f, 0xa0, 0xa4,
                    215:     0x2e, 0x30, 0xef, 0xb5}},
                    216:   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    217:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    218:    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x01, 0x60, 0x46,
                    219:    0x90, 0x85, 0xaf, 0x6f, 0xa2, 0x8d, 0x6a, 0x1d, 0x3e, 0xfd, 0x56, 0xd7,
                    220:    0x57, 0x5e, 0x00, 0x30, 0x5b, 0x49, 0x6c, 0xc4, 0x85, 0xf5, 0x1c, 0x39,
                    221:    0xef, 0x0b, 0x4b, 0x28}
                    222: };
                    223: 
                    224: R_RSA_PUBLIC_KEY PUBLIC_KEY3;
                    225: R_RSA_PRIVATE_KEY PRIVATE_KEY3;
                    226: int KEYPAIR3_READY = 0;
                    227: 
                    228: int main (argc, argv)
                    229: int argc;
                    230: char *argv[];
                    231: {
                    232:   R_RANDOM_STRUCT randomStruct;
                    233:   char command[80];
                    234:   int done = 0;
                    235: 
                    236:   if (SetOptions (argc, argv))
                    237:     return (0);
                    238:   
                    239:   InitRandomStruct (&randomStruct);
                    240:   PrintMessage
                    241:     ("NOTE: When saving to a file, a filename of \"-\" will output to the screen.");
                    242: 
                    243:   while (!done) {
                    244:     PrintMessage ("");
                    245:     PrintMessage ("S - Sign a file");
                    246:     PrintMessage ("E - sEal a file");
                    247:     PrintMessage ("V - Verify a signed file");
                    248:     PrintMessage ("O - Open a sealed file");
                    249:     PrintMessage ("G - Generate a keypair (at least 2 minutes)");
                    250:     PrintMessage ("Q - Quit");
                    251:     GetCommand (command, sizeof (command), "  Enter choice: ");
                    252:     
                    253:     switch (*command) {
                    254:     case '\0':
                    255:     case '#':
                    256:       /* entered a blank line or a comment */
                    257:       break;
                    258:       
                    259:     case 's':
                    260:     case 'S':
                    261:       DoSignFile ();
                    262:       break;
                    263:       
                    264:     case 'e':
                    265:     case 'E':
                    266:       DoSealFile (&randomStruct);
                    267:       break;
                    268:       
                    269:     case 'v':
                    270:     case 'V':
                    271:       DoVerifyFile ();
                    272:       break;
                    273:       
                    274:     case 'o':
                    275:     case 'O':
                    276:       DoOpenFile ();
                    277:       break;
                    278:       
                    279:     case 'g':
                    280:     case 'G':
                    281:       DoGenerateKeys (&randomStruct);
                    282:       break;
                    283:       
                    284:     case 'Q':
                    285:     case 'q':
                    286:       done = 1;
                    287:       break;
                    288:       
                    289:     default:
                    290:       PrintError ("ERROR: Unrecognized command.  Try again.", 0);
                    291:       break;
                    292:     }
                    293:   }
                    294:   
                    295:   R_RandomFinal (&randomStruct);
                    296:   memset ((POINTER)&PRIVATE_KEY3, 0, sizeof (PRIVATE_KEY3));
                    297:   return (0);
                    298: }
                    299: 
                    300: /* Set options from command line and return 0 for success, 1 for bad format.
                    301:  */
                    302: static int SetOptions (argc, argv)
                    303: int argc;
                    304: char *argv[];
                    305: {
                    306:   int i, status = 0;
                    307:   
                    308:   for (i = 1; i < argc; i++) {
                    309:     if (argv[i][0] != '-') {
                    310:       status = 1;
                    311:       break;
                    312:     }
                    313:     
                    314:     if (argv[i][1] == 's')
                    315:       SILENT_PROMPT = 1;
                    316:     else if (argv[i][1] == '2')
                    317:       DIGEST_ALGORITHM = DA_MD2;
                    318:     else {
                    319:       status = 1;
                    320:       break;
                    321:     }
                    322:   }
                    323: 
                    324:   if (status)
                    325:     puts ("Usage: rdemo [-s] [-2]\n\
                    326:   -s silent prompts\n\
                    327:   -2 use MD2 (not MD5)");
                    328: 
                    329:   return (status);
                    330: }
                    331: 
                    332: /* Initialize the random structure with all zero seed bytes for test purposes.
                    333:    NOTE that this will cause the output of the "random" process to be
                    334:      the same every time.  To produce random bytes, the random struct
                    335:      needs random seeds!
                    336:  */
                    337: static void InitRandomStruct (randomStruct)
                    338: R_RANDOM_STRUCT *randomStruct;
                    339: {
                    340:   static unsigned char seedByte = 0;
                    341:   unsigned int bytesNeeded;
                    342:   
                    343:   R_RandomInit (randomStruct);
                    344:   
                    345:   /* Initialize with all zero seed bytes, which will not yield an actual
                    346:        random number output.
                    347:    */
                    348:   while (1) {
                    349:     R_GetRandomBytesNeeded (&bytesNeeded, randomStruct);
                    350:     if (bytesNeeded == 0)
                    351:       break;
                    352:     
                    353:     R_RandomUpdate (randomStruct, &seedByte, 1);
                    354:   }
                    355: }
                    356: 
                    357: static void DoSignFile ()
                    358: {
                    359:   R_RSA_PRIVATE_KEY *privateKey;
                    360:   char command[80];
                    361:   int status, recodeFlag;
                    362:   unsigned char content[1000], encodedContent[1000],
                    363:     encodedSignature[MAX_PEM_SIGNATURE_LEN];
                    364:   unsigned int contentLen, encodedContentLen, encodedSignatureLen;
                    365: 
                    366:   if (ReadText
                    367:       (content, &contentLen, sizeof (content),
                    368:        "  Enter filename of content to sign (blank to cancel): "))
                    369:     return;
                    370:   GetCommand
                    371:     (command, sizeof (command),
                    372:      "  ASCII recode the content [y/n] ? (blank to cancel): ");
                    373:   if (! *command)
                    374:     return;
                    375:   else if (*command == 'y' || *command == 'Y') {
                    376:     if (ENCODED_CONTENT_LEN (contentLen) > sizeof (encodedContent)) {
                    377:       PrintError ("ERROR: Not enough room to recode the content", 0);
                    378:       return;
                    379:     }
                    380:     else
                    381:       recodeFlag = 1;
                    382:   }
                    383:   else
                    384:     recodeFlag = 0;
                    385:   
                    386:   if (GetPrivateKey
                    387:       (&privateKey,
                    388:        "  Sign as user with private key 1, 2, or 3? (blank to cancel): "))
                    389:     return;
                    390:   
                    391:   if (status = R_SignPEMBlock
                    392:       (encodedContent, &encodedContentLen, encodedSignature,
                    393:        &encodedSignatureLen, content, contentLen, recodeFlag,
                    394:        DIGEST_ALGORITHM, privateKey)) {
                    395:     PrintError ("signing file", status);
                    396:     return;
                    397:   }
                    398:   
                    399:   if (WriteBlock
                    400:       (encodedSignature, encodedSignatureLen,
                    401:        "  Enter filename to save the signature (blank to cancel): "))
                    402:     return;
                    403:   
                    404:   if (recodeFlag) {
                    405:     if (WriteBlock
                    406:         (encodedContent, encodedContentLen,
                    407:          "  Enter filename to save the encoded content (blank to cancel): "))
                    408:       return;
                    409:   }
                    410: }
                    411: 
                    412: static void DoSealFile (randomStruct)
                    413: R_RANDOM_STRUCT *randomStruct;
                    414: {
                    415:   R_RSA_PRIVATE_KEY *privateKey;
                    416:   R_RSA_PUBLIC_KEY *publicKey;
                    417:   int status;
                    418:   unsigned char content[1000], encryptedContent[1000],
                    419:     encryptedSignature[MAX_PEM_ENCRYPTED_SIGNATURE_LEN],
                    420:     encryptedKey[MAX_PEM_ENCRYPTED_KEY_LEN], iv[8];
                    421:   unsigned int contentLen, encryptedContentLen, encryptedSignatureLen,
                    422:     encryptedKeyLen;
                    423: 
                    424:   /* Set up a break point with a do {} while (0) so that we can
                    425:        zeroize the sensitive buffers before exiting.
                    426:    */
                    427:   do {
                    428:     if (ReadText
                    429:         (content, &contentLen, sizeof (content),
                    430:          "  Enter filename of content to seal (blank to cancel): "))
                    431:       break;
                    432:     if (ENCRYPTED_CONTENT_LEN (contentLen) > sizeof (encryptedContent)) {
                    433:       PrintError ("ERROR: Not enough room to encrypt the content.", 0);
                    434:       break;
                    435:     }
                    436:   
                    437:     if (GetPrivateKey
                    438:         (&privateKey,
                    439:          "  Sign as user with private key 1, 2, or 3? (blank to cancel): "))
                    440:       break;
                    441:     if (GetPublicKey
                    442:         (&publicKey,
                    443:          "  Seal for user with public key 1, 2, or 3? (blank to cancel): "))
                    444:       break;
                    445:   
                    446:     if (status = R_SealPEMBlock
                    447:         (encryptedContent, &encryptedContentLen, encryptedKey,
                    448:          &encryptedKeyLen, encryptedSignature, &encryptedSignatureLen, iv,
                    449:          content, contentLen, DIGEST_ALGORITHM, publicKey, privateKey,
                    450:          randomStruct)) {
                    451:       PrintError ("sealing file", status);
                    452:       break;
                    453:     }
                    454:   
                    455:     if (WriteBlock
                    456:         (encryptedSignature, encryptedSignatureLen,
                    457:          "  Enter filename to save the signature (blank to cancel): "))
                    458:       break;  
                    459:     if (WriteBlock
                    460:         (encryptedKey, encryptedKeyLen,
                    461:          "  Enter filename to save the encrypted key (blank to cancel): "))
                    462:       break;
                    463:     if (WriteBlock
                    464:         (iv, 8, "  Enter filename to save the key's IV (blank to cancel): "))
                    465:       break;  
                    466:     if (WriteBlock
                    467:         (encryptedContent, encryptedContentLen,
                    468:         "  Enter filename to save the encrypted content (blank to cancel): "))
                    469:       break;
                    470:   } while (0);
                    471:   
                    472:   memset ((POINTER)content, 0, sizeof (content));
                    473: }
                    474: 
                    475: static void DoVerifyFile ()
                    476: {
                    477:   R_RSA_PUBLIC_KEY *publicKey;
                    478:   char command[80];
                    479:   int status, recodeFlag;
                    480:   unsigned char content[1000], encodedContent[1000],
                    481:     encodedSignature[MAX_PEM_SIGNATURE_LEN];
                    482:   unsigned int contentLen, encodedContentLen, encodedSignatureLen;
                    483:   
                    484:   GetCommand
                    485:     (command, sizeof (command),
                    486:      "  Is the file to verify ASCII recoded [y/n] ? (blank to cancel): ");
                    487:   if (! *command)
                    488:     return;  
                    489:   
                    490:   if (*command == 'y' || *command == 'Y') {
                    491:     recodeFlag = 1;
                    492: 
                    493:     if (ReadBlock
                    494:         (encodedContent, &encodedContentLen, sizeof (encodedContent),
                    495:          "  Enter name of file to decode and verify (blank to cancel): "))
                    496:       return;
                    497:     if (DECODED_CONTENT_LEN (encodedContentLen) > sizeof (content)) {
                    498:       PrintError ("ERROR: Not enough room to recode the content", 0);
                    499:       return;
                    500:     }
                    501:   }
                    502:   else {
                    503:     recodeFlag = 0;
                    504:     if (ReadText
                    505:         (encodedContent, &encodedContentLen, sizeof (encodedContent),
                    506:          "  Enter name of file to verify (blank to cancel): "))
                    507:       return;
                    508:   }
                    509: 
                    510:   if (ReadBlock
                    511:       (encodedSignature, &encodedSignatureLen, sizeof (encodedSignature),
                    512:        "  Enter filename of signature (blank to cancel): "))
                    513:     return;
                    514: 
                    515:   if (GetPublicKey
                    516:       (&publicKey,
                    517:        "  Verify signature from user with public key 1, 2, or 3? (blank to cancel): "))
                    518:     return;
                    519:   
                    520:   if (status = R_VerifyPEMSignature
                    521:       (content, &contentLen, encodedContent, encodedContentLen,
                    522:        encodedSignature, encodedSignatureLen, recodeFlag, DIGEST_ALGORITHM,
                    523:        publicKey)) {
                    524:     PrintError ("verifying file", status);
                    525:     return;
                    526:   }
                    527:   else
                    528:     PrintMessage ("Signature verified.");
                    529:   
                    530:   if (recodeFlag) {
                    531:     if (WriteBlock
                    532:         (content, contentLen,
                    533:          "  Enter filename to save the content (blank to cancel): "))
                    534:       return;
                    535:   }
                    536: }
                    537: 
                    538: static void DoOpenFile ()
                    539: {
                    540:   R_RSA_PRIVATE_KEY *privateKey;
                    541:   R_RSA_PUBLIC_KEY *publicKey;
                    542:   int status;
                    543:   unsigned char content[1000], encryptedContent[1000],
                    544:     encryptedSignature[MAX_PEM_ENCRYPTED_SIGNATURE_LEN],
                    545:     encryptedKey[MAX_PEM_ENCRYPTED_KEY_LEN], iv[8];
                    546:   unsigned int contentLen, encryptedContentLen, encryptedSignatureLen,
                    547:     encryptedKeyLen, ivLen;
                    548: 
                    549:   /* Set up a break point with a do {} while (0) so that we can
                    550:        zeroize the sensitive buffers before exiting.
                    551:    */
                    552:   do {
                    553:     if (ReadBlock
                    554:         (encryptedContent, &encryptedContentLen, sizeof (encryptedContent),
                    555:          "  Enter filename of content to open (blank to cancel): "))
                    556:       break;
                    557:     if (DECRYPTED_CONTENT_LEN (encryptedContentLen) > sizeof (content)) {
                    558:       PrintError ("ERROR: Not enough room to decrypt the content.", 0);
                    559:       break;
                    560:     }
                    561:   
                    562:     if (ReadBlock
                    563:         (encryptedSignature, &encryptedSignatureLen,
                    564:          sizeof (encryptedSignature),
                    565:          "  Enter filename the signature (blank to cancel): "))
                    566:       break;  
                    567:     if (ReadBlock
                    568:         (encryptedKey, &encryptedKeyLen, sizeof (encryptedKey),
                    569:          "  Enter filename of the encrypted key (blank to cancel): "))
                    570:       break;  
                    571:     if (ReadBlock
                    572:         (iv, &ivLen, 8,
                    573:          "  Enter filename of the key's IV (blank to cancel): "))
                    574:       break;  
                    575: 
                    576:     if (GetPublicKey
                    577:         (&publicKey,
                    578:          "  Verify signature from user with public key 1, 2, or 3? (blank to cancel): "))
                    579:       break;
                    580:     if (GetPrivateKey
                    581:         (&privateKey,
                    582:          "  Open for user with private key 1, 2, or 3? (blank to cancel): "))
                    583:       break;
                    584:     
                    585:     if (status = R_OpenPEMBlock
                    586:         (content, &contentLen, encryptedContent, encryptedContentLen,
                    587:          encryptedKey, encryptedKeyLen, encryptedSignature,
                    588:          encryptedSignatureLen, iv, DIGEST_ALGORITHM, privateKey,
                    589:          publicKey)) {
                    590:       PrintError ("opening enveloped file", status);
                    591:       break;
                    592:     }
                    593:     else
                    594:       PrintMessage ("Signature verified.");
                    595:   
                    596:     if (WriteBlock
                    597:         (content, contentLen,
                    598:          "  Enter filename to save the decrypted content (blank to cancel): "))
                    599:       break;
                    600:   } while (0);
                    601:   
                    602:   memset ((POINTER)content, 0, sizeof (content));
                    603: }
                    604: 
                    605: static void DoGenerateKeys (randomStruct)
                    606: R_RANDOM_STRUCT *randomStruct;
                    607: {
                    608:   R_RSA_PROTO_KEY protoKey;
                    609:   char command[80];
                    610:   int status, keySize;
                    611: 
                    612:   GetCommand
                    613:     (command, sizeof (command),
                    614:      "  Enter key size in bits, (508 to 1024) (blank to cancel): ");
                    615:   if (! *command)
                    616:     return;
                    617:   sscanf (command, "%d", &keySize);
                    618:   
                    619:   protoKey.bits = (unsigned int)keySize;
                    620:   protoKey.useFermat4 = 1;
                    621:   
                    622:   if (status = R_GeneratePEMKeys
                    623:       (&PUBLIC_KEY3, &PRIVATE_KEY3, &protoKey, randomStruct)) {
                    624:     PrintError ("generating keys", status);
                    625:     return;
                    626:   }
                    627: 
                    628:   PrintMessage ("Public key 3 and private key 3 are now ready to use.");
                    629:   KEYPAIR3_READY = 1;
                    630:   
                    631:   WriteKeypair3 ();
                    632: }
                    633: 
                    634: static void WriteKeypair3 ()
                    635: {
                    636:   FILE *file;
                    637:   char filename[256];
                    638:   
                    639:   while (1) {
                    640:     GetCommand
                    641:       (filename, sizeof (filename),
                    642:        "Enter filename to save the keypair (blank to not save): ");
                    643:     if (! *filename)
                    644:       return;
                    645:     
                    646:     if (filename[0] == '-' && filename[1] == '\0') {
                    647:       /* use stdout */
                    648:       file = stdout;
                    649:       break;
                    650:     }
                    651:     if ((file = fopen (filename, "w")) != NULL)
                    652:       /* successfully opened */
                    653:       break;
                    654:     
                    655:     PrintError ("ERROR: Cannot open a file with that name.  Try again.", 0);
                    656:   }
                    657: 
                    658:   fprintf (file, "Public Key, %u bits:\n", PUBLIC_KEY3.bits);
                    659:   fprintf (file, "  modulus: ");
                    660:   WriteBigInteger (file, PUBLIC_KEY3.modulus, sizeof (PUBLIC_KEY3.modulus));
                    661:   fprintf (file, "  exponent: ");
                    662:   WriteBigInteger (file, PUBLIC_KEY3.exponent, sizeof (PUBLIC_KEY3.exponent));
                    663: 
                    664:   fprintf (file, "\nPrivate Key, %u bits:\n", PRIVATE_KEY3.bits);
                    665:   fprintf (file, "  modulus: ");
                    666:   WriteBigInteger (file, PRIVATE_KEY3.modulus, sizeof (PRIVATE_KEY3.modulus));
                    667:   fprintf (file, "  public exponent: ");
                    668:   WriteBigInteger
                    669:     (file, PRIVATE_KEY3.publicExponent, sizeof (PRIVATE_KEY3.publicExponent));
                    670:   fprintf (file, "  exponent: ");
                    671:   WriteBigInteger
                    672:     (file, PRIVATE_KEY3.exponent, sizeof (PRIVATE_KEY3.exponent));
                    673:   fprintf (file, "  prime 1: ");
                    674:   WriteBigInteger
                    675:     (file, PRIVATE_KEY3.prime[0], sizeof (PRIVATE_KEY3.prime[0]));
                    676:   fprintf (file, "  prime 2: ");
                    677:   WriteBigInteger
                    678:     (file, PRIVATE_KEY3.prime[1], sizeof (PRIVATE_KEY3.prime[1]));
                    679:   fprintf (file, "  prime exponent 1: ");
                    680:   WriteBigInteger
                    681:     (file, PRIVATE_KEY3.primeExponent[0],
                    682:      sizeof (PRIVATE_KEY3.primeExponent[0]));
                    683:   fprintf (file, "  prime exponent 2: ");
                    684:   WriteBigInteger
                    685:     (file, PRIVATE_KEY3.primeExponent[1],
                    686:      sizeof (PRIVATE_KEY3.primeExponent[1]));
                    687:   fprintf (file, "  coefficient: ");
                    688:   WriteBigInteger
                    689:     (file, PRIVATE_KEY3.coefficient, sizeof (PRIVATE_KEY3.coefficient));
                    690: 
                    691:   if (file != stdout)
                    692:     fclose (file);
                    693: }
                    694: 
                    695: /* Write the byte string 'integer' to 'file', skipping over leading zeros.
                    696:  */
                    697: static void WriteBigInteger (file, integer, integerLen)
                    698: FILE *file;
                    699: unsigned char *integer;
                    700: unsigned int integerLen;
                    701: {
                    702:   while (*integer == 0 && integerLen > 0) {
                    703:     integer++;
                    704:     integerLen--;
                    705:   }
                    706:   
                    707:   if (integerLen == 0) {
                    708:     /* Special case, just print a zero. */
                    709:     fprintf (file, "00\n");
                    710:     return;
                    711:   }
                    712:   
                    713:   for (; integerLen > 0; integerLen--)
                    714:     fprintf (file, "%02x ", (unsigned int)(*integer++));
                    715: 
                    716:   fprintf (file, "\n");
                    717: }
                    718: 
                    719: /* Use the prompt to ask the user to use public key 1, 2 or 3 and
                    720:      point publicKey to the answer.
                    721:    Return 0 on success or 1 if user cancels by entering a blank.
                    722:  */
                    723: static int GetPublicKey (publicKey, prompt)
                    724: R_RSA_PUBLIC_KEY **publicKey;
                    725: char *prompt;
                    726: {
                    727:   char command[80];
                    728:   
                    729:   while (1) {
                    730:     GetCommand (command, sizeof (command), prompt);
                    731: 
                    732:     switch (*command) {
                    733:     case '\0':
                    734:       return (1);
                    735:       
                    736:     case '1':
                    737:       *publicKey = &PUBLIC_KEY1;
                    738:       return (0);
                    739:       
                    740:     case '2':
                    741:       *publicKey = &PUBLIC_KEY2;
                    742:       return (0);
                    743:       
                    744:     case '3':
                    745:       if (!KEYPAIR3_READY) {
                    746:         PrintError
                    747:           ("ERROR: Public key 3 has not been generated yet.  Try Again.", 0);
                    748:         break;
                    749:       }
                    750:       else {
                    751:         *publicKey = &PUBLIC_KEY3;
                    752:         return (0);
                    753:       }
                    754:       
                    755:     default:
                    756:       if (KEYPAIR3_READY)
                    757:         PrintError ("ERROR: Please enter 1, 2 or 3.  Try again.", 0);
                    758:       else
                    759:         PrintError ("ERROR: Please enter 1 or 2.  Try again.", 0);
                    760:       break;
                    761:     }
                    762:   }
                    763: }
                    764: 
                    765: /* Use the prompt to ask the user to use private key 1, 2 or 3 and
                    766:      point privateKey to the answer.
                    767:    Return 0 on success or 1 if user cancels by entering a blank.
                    768:  */
                    769: static int GetPrivateKey (privateKey, prompt)
                    770: R_RSA_PRIVATE_KEY **privateKey;
                    771: char *prompt;
                    772: {
                    773:   char command[80];
                    774:   
                    775:   while (1) {
                    776:     GetCommand (command, sizeof (command), prompt);
                    777: 
                    778:     switch (*command) {
                    779:     case '\0':
                    780:       return (1);
                    781:       
                    782:     case '1':
                    783:       *privateKey = &PRIVATE_KEY1;
                    784:       return (0);
                    785:       
                    786:     case '2':
                    787:       *privateKey = &PRIVATE_KEY2;
                    788:       return (0);
                    789:       
                    790:     case '3':
                    791:       if (!KEYPAIR3_READY) {
                    792:         PrintError
                    793:           ("ERROR: Private key 3 has not been generated yet.  Try Again.", 0);
                    794:         break;
                    795:       }
                    796:       else {
                    797:         *privateKey = &PRIVATE_KEY3;
                    798:         return (0);
                    799:       }
                    800:       
                    801:     default:
                    802:       if (KEYPAIR3_READY)
                    803:         PrintError ("ERROR: Please enter 1, 2 or 3.  Try again.", 0);
                    804:       else
                    805:         PrintError ("ERROR: Please enter 1 or 2.  Try again.", 0);
                    806:       break;
                    807:     }
                    808:   }
                    809: }
                    810: 
                    811: /* Read a file of up to length maxBlockLen bytes, storing it in
                    812:      block and returning its length in blockLen.
                    813:    Ask for the filename using the given prompt string.
                    814:    Return 0 on success or 1 if error or if user cancels by entering a blank.
                    815:  */
                    816: static int ReadBlock (block, blockLen, maxBlockLen, prompt) 
                    817: unsigned char *block;
                    818: unsigned int *blockLen;
                    819: unsigned int maxBlockLen;
                    820: char *prompt;
                    821: {
                    822:   FILE *file;
                    823:   int status;
                    824:   char filename[256];
                    825:   unsigned char dummy;
                    826:   
                    827:   while (1) {
                    828:     GetCommand (filename, sizeof (filename), prompt);
                    829:     if (! *filename)
                    830:       return (1);
                    831:     
                    832:     if ((file = fopen (filename, "rb")) != NULL)
                    833:       /* successfully opened */
                    834:       break;
                    835:     
                    836:     PrintError ("ERROR: Cannot open a file with that name.  Try again.", 0);
                    837:   }
                    838:   
                    839:   /* fread () returns the number of items read in.  Expect an end of file
                    840:        after the read.
                    841:    */
                    842:   *blockLen = fread (block, 1, maxBlockLen, file);
                    843:   if (*blockLen == maxBlockLen)
                    844:     /* Read exactly maxBlockLen bytes, so reading one more will set 
                    845:          end of file if there were exactly maxBlockLen bytes in the file.
                    846:      */
                    847:     fread (&dummy, 1, 1, file);
                    848:   
                    849:   if (!feof (file)) {
                    850:     PrintError ("ERROR: Cannot read file or file is too large.", 0);
                    851:     status = 1;
                    852:   }
                    853:   else
                    854:     status = 0;
                    855:   
                    856:   fclose (file);
                    857:   return (status);
                    858: }
                    859: 
                    860: /* Read a file of up to length maxBlockLen bytes, storing it in
                    861:      block and returning its length in blockLen.
                    862:    Ask for the filename using the given prompt string.
                    863:    Read the file using fgets and convert all end of line characters to the
                    864:      canonical CR/LF.
                    865:    Return 0 on success or 1 if error or if user cancels by entering a blank.
                    866:  */
                    867: static int ReadText (block, blockLen, maxBlockLen, prompt) 
                    868: unsigned char *block;
                    869: unsigned int *blockLen;
                    870: unsigned int maxBlockLen;
                    871: char *prompt;
                    872: {
                    873:   FILE *file;
                    874:   int status;
                    875:   char filename[256];
                    876:   unsigned int lineLen;
                    877:   
                    878:   while (1) {
                    879:     GetCommand (filename, sizeof (filename), prompt);
                    880:     if (! *filename)
                    881:       return (1);
                    882:     
                    883:     if ((file = fopen (filename, "rb")) != NULL)
                    884:       /* successfully opened */
                    885:       break;
                    886:     
                    887:     PrintError ("ERROR: Cannot open a file with that name.  Try again.", 0);
                    888:   }
                    889: 
                    890:   status = 0;
                    891:   *blockLen = 0;
                    892:   while (1) {
                    893:     /* fgets returns a null-terminated string which includes the end of
                    894:        line characters.
                    895:      */
                    896:     if (fgets ((char *)(block + *blockLen), maxBlockLen - *blockLen, file)
                    897:         == NULL) {
                    898:       if (!feof (file))
                    899:         status = 1;        
                    900:       break;
                    901:     }
                    902:       
                    903:     /* Strip of end of line characters.
                    904:      */
                    905:     lineLen = strlen ((char *)(block + *blockLen));
                    906:     while (lineLen > 0 && block[*blockLen + lineLen - 1] == 10 ||
                    907:            block[*blockLen + lineLen - 1] == 13)
                    908:       lineLen --;
                    909:     
                    910:     /* Now try to add CR/LF.
                    911:      */
                    912:     (*blockLen) += lineLen;
                    913:     if (*blockLen + 2 > maxBlockLen) {
                    914:       /* Not enough room for CR/LF. */
                    915:       status = 1;
                    916:       break;
                    917:     }
                    918:     block[(*blockLen)++] = 13;
                    919:     block[(*blockLen)++] = 10;
                    920:   }
                    921:   
                    922:   if (status)
                    923:     PrintError ("ERROR: Cannot read file or file is too large.", 0);  
                    924:   fclose (file);
                    925:   return (status);
                    926: }
                    927: 
                    928: /* Write block oflength blockLen to a file.
                    929:    Ask for the filename using the given prompt string.
                    930:    Return 0 on success or 1 if error or if user cancels by entering a blank.
                    931:  */
                    932: static int WriteBlock (block, blockLen, prompt) 
                    933: unsigned char *block;
                    934: unsigned int blockLen;
                    935: char *prompt;
                    936: {
                    937:   FILE *file;
                    938:   int status;
                    939:   char filename[256];
                    940:   
                    941:   while (1) {
                    942:     GetCommand (filename, sizeof (filename), prompt);
                    943:     if (! *filename)
                    944:       return (1);
                    945:     
                    946:     if (filename[0] == '-' && filename[1] == '\0') {
                    947:       /* use stdout */
                    948:       file = stdout;
                    949:       break;
                    950:     }
                    951:     if ((file = fopen (filename, "wb")) != NULL)
                    952:       /* successfully opened */
                    953:       break;
                    954:     
                    955:     PrintError ("ERROR: Cannot open a file with that name.  Try again.", 0);
                    956:   }
                    957:   
                    958:   status = 0;
                    959:   if (fwrite (block, 1, blockLen, file) < blockLen) {
                    960:     PrintError ("ERROR: Cannot write file.", 0);
                    961:     status = 1;
                    962:   }
                    963:   else {
                    964:     if (file == stdout)
                    965:       /* Printing to screen, so print a new line. */
                    966:       printf ("\n");
                    967:   }
                    968: 
                    969:   if (file != stdout)
                    970:     fclose (file);
                    971:   return (status);
                    972: }
                    973: 
                    974: static void PrintMessage (message)
                    975: char *message;
                    976: {
                    977:   if (!SILENT_PROMPT) {
                    978:     puts (message);
                    979:     fflush (stdout);
                    980:   }
                    981: }
                    982: 
                    983: /* If type is zero, simply print the task string, otherwise convert the
                    984:      type to a string and print task and type.
                    985:  */
                    986: static void PrintError (task, type)
                    987: char *task;
                    988: int type;
                    989: {
                    990:   char *typeString, buf[80];
                    991: 
                    992:   if (type == 0) {
                    993:     puts (task);
                    994:     return;
                    995:   }
                    996:   
                    997:   /* Convert the type to a string if it is recognized.
                    998:    */
                    999:   switch (type) {
                   1000:   case RE_CONTENT_ENCODING:
                   1001:     typeString = "(Encrypted) content has RFC 1113 encoding error";
                   1002:     break;
                   1003:   case RE_DIGEST_ALGORITHM:
                   1004:     typeString = "Message-digest algorithm is invalid";
                   1005:     break;
                   1006:   case RE_KEY:
                   1007:     typeString = "Recovered DES key cannot decrypt encrypted content or encrypt signature";
                   1008:     break;
                   1009:   case RE_KEY_ENCODING:
                   1010:     typeString = "Encrypted key has RFC 1113 encoding error";
                   1011:     break;
                   1012:   case RE_MODULUS_LEN:
                   1013:     typeString = "Modulus length is invalid";
                   1014:     break;
                   1015:   case RE_NEED_RANDOM:
                   1016:     typeString = "Random structure is not seeded";
                   1017:     break;
                   1018:   case RE_PRIVATE_KEY:
                   1019:     typeString = "Private key cannot encrypt message digest, or cannot decrypt encrypted key";
                   1020:     break;
                   1021:   case RE_PUBLIC_KEY:
                   1022:     typeString = "Public key cannot encrypt DES key, or cannot decrypt signature";
                   1023:     break;
                   1024:   case RE_SIGNATURE:
                   1025:     typeString = "Signature on content or block is incorrect";
                   1026:     break;
                   1027:   case RE_SIGNATURE_ENCODING:
                   1028:     typeString = "(Encrypted) signature has RFC 1113 encoding error";
                   1029:     break;
                   1030:     
                   1031:   default:
                   1032:     sprintf (buf, "Code 0x%04x", type);
                   1033:     typeString = buf;
                   1034:   }
                   1035: 
                   1036:   printf ("ERROR: %s while %s\n", typeString, task);  
                   1037:   fflush (stdout);
                   1038: }
                   1039: 
                   1040: static void GetCommand (command, maxCommandSize, prompt)
                   1041: char *command;
                   1042: unsigned int maxCommandSize;
                   1043: char *prompt;
                   1044: {
                   1045:   unsigned int i;
                   1046:   
                   1047:   if (!SILENT_PROMPT) {
                   1048:     printf ("%s\n", prompt);  
                   1049:     fflush (stdout);
                   1050:   }
                   1051: 
                   1052:   fgets (command, maxCommandSize, stdin);
                   1053:   
                   1054:   /* Replace the line terminator with a '\0'.
                   1055:    */
                   1056:   for (i = 0; command[i] != '\0'; i++) {
                   1057:     if (command[i] == '\012' || command[i] == '\015' ||
                   1058:         i == (maxCommandSize - 1)) {
                   1059:       command[i] = '\0';
                   1060:       return;
                   1061:     }
                   1062:   }
                   1063: }
                   1064: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.