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

1.1       root        1: /* RDEMO.C - RSAREF demonstration program
                      2:  */
                      3: 
1.1.1.2 ! root        4: /* Copyright (C) 1991-4 RSA Laboratories, a division of RSA Data
1.1       root        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));
1.1.1.2 ! root       18: static void DoSealFile PROTO_LIST ((R_RANDOM_STRUCT *));
1.1       root       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));
1.1.1.2 ! root       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 *));
1.1       root       28: static int ReadBlock PROTO_LIST
                     29:   ((unsigned char *, unsigned int *, unsigned int, char *));
1.1.1.2 ! root       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 *));
1.1       root       33: static int WriteBlock PROTO_LIST ((unsigned char *, unsigned int, char *));
1.1.1.2 ! root       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 *));
1.1       root       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");
1.1.1.2 ! root      253:     PrintMessage ("E - sEal a file");
1.1       root      254:     PrintMessage ("O - Open a sealed file");
1.1.1.2 ! root      255:     PrintMessage ("G - Generate a keypair (may take a long time)");
1.1       root      256:     PrintMessage ("Q - Quit");
1.1.1.2 ! root      257:     GetCommand (command, sizeof (command), "  Enter choice");
1.1       root      258:     
                    259:     switch (*command) {
                    260:     case '#':
1.1.1.2 ! root      261:       /* entered a comment */
1.1       root      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:       
1.1.1.2 ! root      274:     case 'e':
        !           275:     case 'E':
        !           276:       DoSealFile (&randomStruct);
        !           277:       break;
        !           278: 
1.1       root      279:     case 'o':
                    280:     case 'O':
                    281:       DoOpenFile ();
                    282:       break;
                    283:       
                    284:     case 'g':
                    285:     case 'G':
                    286:       DoGenerateKeys (&randomStruct);
                    287:       break;
                    288:       
1.1.1.2 ! root      289:     case '\0':
1.1       root      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);
1.1.1.2 ! root      302:   R_memset ((POINTER)&PRIVATE_KEY3, 0, sizeof (PRIVATE_KEY3));
1.1       root      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)
1.1.1.2 ! root      329:     puts ("Usage: rdemo [-s]\n\
        !           330:   -s silent prompts\n");
1.1       root      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: {
1.1.1.2 ! root      362:   FILE *file;
1.1       root      363:   R_RSA_PRIVATE_KEY *privateKey;
1.1.1.2 ! root      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"))
1.1       root      372:     return;
1.1.1.2 ! root      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)
1.1       root      402:     PrintError ("signing file", status);
1.1.1.2 ! root      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"))
1.1       root      420:     return;
1.1.1.2 ! root      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));
1.1       root      457: }
                    458: 
                    459: static void DoSealFile (randomStruct)
                    460: R_RANDOM_STRUCT *randomStruct;
                    461: {
1.1.1.2 ! root      462:   FILE *inFile, *outFile;
        !           463:   R_ENVELOPE_CTX context;
1.1       root      464:   R_RSA_PUBLIC_KEY *publicKey;
1.1.1.2 ! root      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:   }
1.1       root      478: 
                    479:   do {
1.1.1.2 ! root      480:     if (GetPublicKey (&publicKey))
1.1       root      481:       break;
1.1.1.2 ! root      482: 
        !           483:     if (GetEncryptionAlgorithm (&encryptionAlgorithm))
1.1       root      484:       break;
1.1.1.2 ! root      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);
1.1       root      498:     }
1.1.1.2 ! root      499:     if (status)
1.1       root      500:       break;
1.1.1.2 ! root      501: 
        !           502:     if ((status = R_SealFinal (&context, partOut, &partOutLen)))
1.1       root      503:       break;
1.1.1.2 ! root      504:     WriteUpdate (outFile, partOut, partOutLen);
1.1       root      505:   
                    506:     if (WriteBlock
                    507:         (encryptedKey, encryptedKeyLen,
1.1.1.2 ! root      508:          "  Enter filename to save the encrypted key"))
1.1       root      509:       break;
                    510:     if (WriteBlock
1.1.1.2 ! root      511:         (iv, 8, "  Enter filename to save the initializing vector"))
1.1       root      512:       break;
                    513:   } while (0);
                    514:   
1.1.1.2 ! root      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));
1.1       root      523: }
                    524: 
1.1.1.2 ! root      525: static void DoOpenFile ()
1.1       root      526: {
1.1.1.2 ! root      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;
1.1       root      534: 
1.1.1.2 ! root      535:   status = 0;
1.1       root      536: 
1.1.1.2 ! root      537:   if (ReadInit (&inFile, "  Enter filename of encrypted content to open"))
1.1       root      538:     return;
                    539: 
1.1.1.2 ! root      540:   if (WriteInit (&outFile, "  Enter filename to save the recovered content")) {
        !           541:     ReadFinal (inFile);
1.1       root      542:     return;
                    543:   }
                    544: 
                    545:   do {
1.1.1.2 ! root      546:     if (GetPrivateKey (&privateKey))
1.1       root      547:       break;
1.1.1.2 ! root      548: 
        !           549:     if (GetEncryptionAlgorithm (&encryptionAlgorithm))
1.1       root      550:       break;
1.1.1.2 ! root      551: 
1.1       root      552:     if (ReadBlock
                    553:         (encryptedKey, &encryptedKeyLen, sizeof (encryptedKey),
1.1.1.2 ! root      554:          "  Enter filename of the encrypted key"))
1.1       root      555:       break;  
                    556:     if (ReadBlock
1.1.1.2 ! root      557:         (iv, &ivLen, 8, "  Enter filename of the initializing vector"))
        !           558:       break;
1.1       root      559: 
1.1.1.2 ! root      560:     if ((status = R_OpenInit
        !           561:          (&context, encryptionAlgorithm, encryptedKey, encryptedKeyLen, iv,
        !           562:           privateKey)) != 0)
1.1       root      563:       break;
                    564:     
1.1.1.2 ! root      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);
1.1       root      570:     }
1.1.1.2 ! root      571:     if (status)
        !           572:       break;
        !           573: 
        !           574:     if ((status = R_OpenFinal (&context, partOut, &partOutLen)) != 0)
1.1       root      575:       break;
1.1.1.2 ! root      576:     WriteUpdate (outFile, partOut, partOutLen);
1.1       root      577:   } while (0);
                    578:   
1.1.1.2 ! root      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));
1.1       root      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),
1.1.1.2 ! root      598:      "  Enter key size in bits, (508 to 1024)");
1.1       root      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),
1.1.1.2 ! root      626:        "  Enter filename to save the keypair");
1.1       root      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: 
1.1.1.2 ! root      703: /* Ask the user to use public key 1, 2 or 3 and point publicKey to
        !           704:      the answer.
1.1       root      705:    Return 0 on success or 1 if user cancels by entering a blank.
                    706:  */
1.1.1.2 ! root      707: static int GetPublicKey (publicKey)
1.1       root      708: R_RSA_PUBLIC_KEY **publicKey;
                    709: {
                    710:   char command[80];
                    711:   
                    712:   while (1) {
1.1.1.2 ! root      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?");
1.1       root      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':
1.1.1.2 ! root      731:       if (!KEYPAIR3_READY)
1.1       root      732:         break;
1.1.1.2 ! root      733:       *publicKey = &PUBLIC_KEY3;
        !           734:       return (0);
1.1       root      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: 
1.1.1.2 ! root      746: /* Ask the user to use private key 1, 2 or 3 and point privateKey to
        !           747:      the answer.
1.1       root      748:    Return 0 on success or 1 if user cancels by entering a blank.
                    749:  */
1.1.1.2 ! root      750: static int GetPrivateKey (privateKey)
1.1       root      751: R_RSA_PRIVATE_KEY **privateKey;
                    752: {
                    753:   char command[80];
                    754:   
                    755:   while (1) {
1.1.1.2 ! root      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?");
1.1       root      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':
1.1.1.2 ! root      774:       if (!KEYPAIR3_READY)
1.1       root      775:         break;
1.1.1.2 ! root      776:       *privateKey = &PRIVATE_KEY3;
        !           777:       return (0);
1.1       root      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: 
1.1.1.2 ! root      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.
1.1       root      864:    Return 0 on success or 1 if error or if user cancels by entering a blank.
                    865:  */
1.1.1.2 ! root      866: static int ReadInit (file, prompt) 
        !           867: FILE **file;
1.1       root      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:     
1.1.1.2 ! root      877:     if ((*file = fopen (filename, "rb")) != NULL)
1.1       root      878:       /* successfully opened */
                    879:       break;
                    880:     
                    881:     PrintError ("ERROR: Cannot open a file with that name.  Try again.", 0);
                    882:   }
1.1.1.2 ! root      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;
1.1       root      898:   
1.1.1.2 ! root      899:   /* fread () returns the number of items read in.
1.1       root      900:    */
1.1.1.2 ! root      901:   *partOutLen = fread (partOut, 1, maxPartOutLen, file);
        !           902: 
        !           903:   status = 0;
        !           904:   if (ferror (file)) {
        !           905:     PrintError ("ERROR: Cannot read file.", 0);
1.1       root      906:     status = 1;
                    907:   }
1.1.1.2 ! root      908:   if (*partOutLen == 0 && feof (file))
        !           909:     status = 1;
        !           910: 
1.1       root      911:   return (status);
                    912: }
                    913: 
1.1.1.2 ! root      914: /* Close file.
        !           915:  */
        !           916: static void ReadFinal (file)
        !           917: FILE *file;
        !           918: {
        !           919:   fclose (file);
        !           920: }
        !           921: 
1.1       root      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:  */
1.1.1.2 ! root      927: static int ReadBlock (block, blockLen, maxBlockLen, prompt) 
1.1       root      928: unsigned char *block;
                    929: unsigned int *blockLen;
                    930: unsigned int maxBlockLen;
                    931: char *prompt;
                    932: {
                    933:   FILE *file;
                    934:   int status;
1.1.1.2 ! root      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: {
1.1       root      965:   char filename[256];
                    966:   
                    967:   while (1) {
                    968:     GetCommand (filename, sizeof (filename), prompt);
                    969:     if (! *filename)
                    970:       return (1);
                    971:     
1.1.1.2 ! root      972:     if (filename[0] == '-' && filename[1] == '\0') {
        !           973:       /* use stdout */
        !           974:       *file = stdout;
        !           975:       break;
        !           976:     }
        !           977:     if ((*file = fopen (filename, "wb")) != NULL)
1.1       root      978:       /* successfully opened */
                    979:       break;
                    980:     
                    981:     PrintError ("ERROR: Cannot open a file with that name.  Try again.", 0);
                    982:   }
                    983: 
1.1.1.2 ! root      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: 
1.1       root      997:   status = 0;
1.1.1.2 ! root      998:   if (fwrite (partOut, 1, partOutLen, file) < partOutLen) {
        !           999:     PrintError ("ERROR: Cannot write file.", 0);
        !          1000:     status = 1;
1.1       root     1001:   }
                   1002:   
                   1003:   return (status);
                   1004: }
                   1005: 
1.1.1.2 ! root     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.
1.1       root     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;
1.1.1.2 ! root     1026: 
        !          1027:   if (WriteInit (&file, prompt))
        !          1028:     return (1);
        !          1029: 
        !          1030:   do {
        !          1031:     if ((status = WriteUpdate (file, block, blockLen)) != 0)
1.1       root     1032:       break;
                   1033:   
                   1034:     if (file == stdout)
                   1035:       /* Printing to screen, so print a new line. */
                   1036:       printf ("\n");
1.1.1.2 ! root     1037:   } while (0);
        !          1038: 
        !          1039:   WriteFinal (file);
1.1       root     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:
1.1.1.2 ! root     1071:     typeString = "Recovered DES key cannot decrypt encrypted content";
1.1       root     1072:     break;
1.1.1.2 ! root     1073:   case RE_LEN:
        !          1074:     typeString = "Encrypted key length or signature length is out of range";
1.1       root     1075:     break;
                   1076:   case RE_MODULUS_LEN:
1.1.1.2 ! root     1077:     typeString = "Modulus length is out of range";
1.1       root     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:
1.1.1.2 ! root     1083:     typeString = "Public key cannot encrypt data encryption key, or cannot decrypt signature";
1.1       root     1084:     break;
                   1085:   case RE_SIGNATURE:
1.1.1.2 ! root     1086:     typeString = "Signature is incorrect";
1.1       root     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) {
1.1.1.2 ! root     1106:     printf ("%s (blank to cancel): \n", prompt);  
1.1       root     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.