|
|
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.