1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
53 #define BPB 8 /* bits per byte. */
58 const SEC_ASN1Template seckey_PQGParamsTemplate
[] = {
59 { SEC_ASN1_SEQUENCE
, 0, NULL
, sizeof(SECKEYPQGParams
) },
60 { SEC_ASN1_INTEGER
, offsetof(SECKEYPQGParams
,prime
) },
61 { SEC_ASN1_INTEGER
, offsetof(SECKEYPQGParams
,subPrime
) },
62 { SEC_ASN1_INTEGER
, offsetof(SECKEYPQGParams
,base
) },
71 fprintf(stderr
, "Usage: %s\n", progName
);
73 "-a Output DER-encoded PQG params, BTOA encoded.\n"
74 " -l prime-length Length of prime in bits (1024 is default)\n"
75 " -o file Output to this file (default is stdout)\n"
76 "-b Output DER-encoded PQG params in binary\n"
77 " -l prime-length Length of prime in bits (1024 is default)\n"
78 " -o file Output to this file (default is stdout)\n"
79 "-r Output P, Q and G in ASCII hexadecimal. \n"
80 " -l prime-length Length of prime in bits (1024 is default)\n"
81 " -o file Output to this file (default is stdout)\n"
82 "-g bits Generate SEED this many bits long.\n"
89 outputPQGParams(PQGParams
* pqgParams
, PRBool output_binary
, PRBool output_raw
,
92 PRArenaPool
* arena
= NULL
;
97 SECItem encodedParams
;
102 rv
= PK11_PQG_GetPrimeFromParams(pqgParams
, &item
);
104 SECU_PrintError(progName
, "PK11_PQG_GetPrimeFromParams");
107 SECU_PrintInteger(outFile
, &item
, "Prime", 1);
108 SECITEM_FreeItem(&item
, PR_FALSE
);
110 rv
= PK11_PQG_GetSubPrimeFromParams(pqgParams
, &item
);
112 SECU_PrintError(progName
, "PK11_PQG_GetPrimeFromParams");
115 SECU_PrintInteger(outFile
, &item
, "Subprime", 1);
116 SECITEM_FreeItem(&item
, PR_FALSE
);
118 rv
= PK11_PQG_GetBaseFromParams(pqgParams
, &item
);
120 SECU_PrintError(progName
, "PK11_PQG_GetPrimeFromParams");
123 SECU_PrintInteger(outFile
, &item
, "Base", 1);
124 SECITEM_FreeItem(&item
, PR_FALSE
);
126 fprintf(outFile
, "\n");
130 encodedParams
.data
= NULL
;
131 encodedParams
.len
= 0;
132 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
134 SECU_PrintError(progName
, "PORT_NewArena");
137 pItem
= SEC_ASN1EncodeItem(arena
, &encodedParams
, pqgParams
,
138 seckey_PQGParamsTemplate
);
140 SECU_PrintError(progName
, "SEC_ASN1EncodeItem");
141 PORT_FreeArena(arena
, PR_FALSE
);
146 len
= fwrite(encodedParams
.data
, 1, encodedParams
.len
, outFile
);
147 PORT_FreeArena(arena
, PR_FALSE
);
148 if (len
!= encodedParams
.len
) {
149 fprintf(stderr
, "%s: fwrite failed\n", progName
);
155 /* must be output ASCII */
156 PQG
= BTOA_DataToAscii(encodedParams
.data
, encodedParams
.len
);
157 PORT_FreeArena(arena
, PR_FALSE
);
159 SECU_PrintError(progName
, "BTOA_DataToAscii");
163 cc
= fprintf(outFile
,"%s\n",PQG
);
166 fprintf(stderr
, "%s: fprintf failed\n", progName
);
173 outputPQGVerify(PQGVerify
* pqgVerify
, PRBool output_binary
, PRBool output_raw
,
176 SECStatus rv
= SECSuccess
;
179 unsigned int counter
;
181 rv
= PK11_PQG_GetHFromVerify(pqgVerify
, &item
);
183 SECU_PrintError(progName
, "PK11_PQG_GetHFromVerify");
186 SECU_PrintInteger(outFile
, &item
, "h", 1);
187 SECITEM_FreeItem(&item
, PR_FALSE
);
189 rv
= PK11_PQG_GetSeedFromVerify(pqgVerify
, &item
);
191 SECU_PrintError(progName
, "PK11_PQG_GetSeedFromVerify");
194 SECU_PrintInteger(outFile
, &item
, "SEED", 1);
195 fprintf(outFile
, " g: %d\n", item
.len
* BPB
);
196 SECITEM_FreeItem(&item
, PR_FALSE
);
198 counter
= PK11_PQG_GetCounterFromVerify(pqgVerify
);
199 fprintf(outFile
, " counter: %d\n", counter
);
200 fprintf(outFile
, "\n");
206 main(int argc
, char **argv
)
208 FILE * outFile
= NULL
;
209 char * outFileName
= NULL
;
210 PQGParams
* pqgParams
= NULL
;
211 PQGVerify
* pqgVerify
= NULL
;
212 int keySizeInBits
= 1024;
216 SECStatus passed
= 0;
217 PRBool output_ascii
= PR_FALSE
;
218 PRBool output_binary
= PR_FALSE
;
219 PRBool output_raw
= PR_FALSE
;
220 PLOptState
*optstate
;
224 progName
= strrchr(argv
[0], '/');
226 progName
= strrchr(argv
[0], '\\');
227 progName
= progName
? progName
+1 : argv
[0];
229 /* Parse command line arguments */
230 optstate
= PL_CreateOptState(argc
, argv
, "?abg:l:o:r" );
231 while ((status
= PL_GetNextOpt(optstate
)) == PL_OPT_OK
) {
232 switch (optstate
->option
) {
235 keySizeInBits
= atoi(optstate
->value
);
239 output_ascii
= PR_TRUE
;
243 output_binary
= PR_TRUE
;
247 output_raw
= PR_TRUE
;
252 PORT_Free(outFileName
);
254 outFileName
= PORT_Strdup(optstate
->value
);
261 g
= atoi(optstate
->value
);
271 PL_DestroyOptState(optstate
);
273 if (status
== PL_OPT_BAD
) {
277 /* exactly 1 of these options must be set. */
278 if (1 != ((output_ascii
!= PR_FALSE
) +
279 (output_binary
!= PR_FALSE
) +
280 (output_raw
!= PR_FALSE
))) {
284 j
= PQG_PBITS_TO_INDEX(keySizeInBits
);
286 fprintf(stderr
, "%s: Illegal prime length, \n"
287 "\tacceptable values are between 512 and 1024,\n"
288 "\tand divisible by 64\n", progName
);
291 if (g
!= 0 && (g
< 160 || g
>= 2048 || g
% 8 != 0)) {
292 fprintf(stderr
, "%s: Illegal g bits, \n"
293 "\tacceptable values are between 160 and 2040,\n"
294 "\tand divisible by 8\n", progName
);
298 if (!rv
&& outFileName
) {
299 outFile
= fopen(outFileName
, output_binary
? "wb" : "w");
301 fprintf(stderr
, "%s: unable to open \"%s\" for writing\n",
302 progName
, outFileName
);
307 PORT_Free(outFileName
);
313 if (outFile
== NULL
) {
321 rv
= PK11_PQG_ParamGenSeedLen((unsigned)j
, (unsigned)(g
/8),
322 &pqgParams
, &pqgVerify
);
324 rv
= PK11_PQG_ParamGen((unsigned)j
, &pqgParams
, &pqgVerify
);
325 /* below here, must go to loser */
327 if (rv
!= SECSuccess
|| pqgParams
== NULL
|| pqgVerify
== NULL
) {
328 SECU_PrintError(progName
, "PQG parameter generation failed.\n");
331 fprintf(stderr
, "%s: PQG parameter generation completed.\n", progName
);
333 rv
= outputPQGParams(pqgParams
, output_binary
, output_raw
, outFile
);
335 fprintf(stderr
, "%s: failed to output PQG params.\n", progName
);
338 rv
= outputPQGVerify(pqgVerify
, output_binary
, output_raw
, outFile
);
340 fprintf(stderr
, "%s: failed to output PQG Verify.\n", progName
);
344 rv
= PK11_PQG_VerifyParams(pqgParams
, pqgVerify
, &passed
);
345 if (rv
!= SECSuccess
) {
346 fprintf(stderr
, "%s: PQG parameter verification aborted.\n", progName
);
349 if (passed
!= SECSuccess
) {
350 fprintf(stderr
, "%s: PQG parameters failed verification.\n", progName
);
353 fprintf(stderr
, "%s: PQG parameters passed verification.\n", progName
);
355 PK11_PQG_DestroyParams(pqgParams
);
356 PK11_PQG_DestroyVerify(pqgVerify
);
360 PK11_PQG_DestroyParams(pqgParams
);
361 PK11_PQG_DestroyVerify(pqgVerify
);