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