|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.