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

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

unix.superglobalmegacorp.com

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