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