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