1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
21 #define BPB 8 /* bits per byte. */
26 const SEC_ASN1Template seckey_PQGParamsTemplate
[] = {
27 { SEC_ASN1_SEQUENCE
, 0, NULL
, sizeof(SECKEYPQGParams
) },
28 { SEC_ASN1_INTEGER
, offsetof(SECKEYPQGParams
,prime
) },
29 { SEC_ASN1_INTEGER
, offsetof(SECKEYPQGParams
,subPrime
) },
30 { SEC_ASN1_INTEGER
, offsetof(SECKEYPQGParams
,base
) },
39 fprintf(stderr
, "Usage: %s\n", progName
);
41 "-a Output DER-encoded PQG params, BTOA encoded.\n"
42 "-b Output DER-encoded PQG params in binary\n"
43 "-r Output P, Q and G in ASCII hexadecimal. \n"
44 " -l prime-length Length of prime in bits (1024 is default)\n"
45 " -n subprime-length Length of subprime in bits\n"
46 " -o file Output to this file (default is stdout)\n"
47 " -g bits Generate SEED this many bits long.\n"
54 outputPQGParams(PQGParams
* pqgParams
, PRBool output_binary
, PRBool output_raw
,
57 PLArenaPool
* arena
= NULL
;
62 SECItem encodedParams
;
67 rv
= PK11_PQG_GetPrimeFromParams(pqgParams
, &item
);
69 SECU_PrintError(progName
, "PK11_PQG_GetPrimeFromParams");
72 SECU_PrintInteger(outFile
, &item
, "Prime", 1);
73 SECITEM_FreeItem(&item
, PR_FALSE
);
75 rv
= PK11_PQG_GetSubPrimeFromParams(pqgParams
, &item
);
77 SECU_PrintError(progName
, "PK11_PQG_GetPrimeFromParams");
80 SECU_PrintInteger(outFile
, &item
, "Subprime", 1);
81 SECITEM_FreeItem(&item
, PR_FALSE
);
83 rv
= PK11_PQG_GetBaseFromParams(pqgParams
, &item
);
85 SECU_PrintError(progName
, "PK11_PQG_GetPrimeFromParams");
88 SECU_PrintInteger(outFile
, &item
, "Base", 1);
89 SECITEM_FreeItem(&item
, PR_FALSE
);
91 fprintf(outFile
, "\n");
95 encodedParams
.data
= NULL
;
96 encodedParams
.len
= 0;
97 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
99 SECU_PrintError(progName
, "PORT_NewArena");
102 pItem
= SEC_ASN1EncodeItem(arena
, &encodedParams
, pqgParams
,
103 seckey_PQGParamsTemplate
);
105 SECU_PrintError(progName
, "SEC_ASN1EncodeItem");
106 PORT_FreeArena(arena
, PR_FALSE
);
111 len
= fwrite(encodedParams
.data
, 1, encodedParams
.len
, outFile
);
112 PORT_FreeArena(arena
, PR_FALSE
);
113 if (len
!= encodedParams
.len
) {
114 fprintf(stderr
, "%s: fwrite failed\n", progName
);
120 /* must be output ASCII */
121 PQG
= BTOA_DataToAscii(encodedParams
.data
, encodedParams
.len
);
122 PORT_FreeArena(arena
, PR_FALSE
);
124 SECU_PrintError(progName
, "BTOA_DataToAscii");
128 cc
= fprintf(outFile
,"%s\n",PQG
);
131 fprintf(stderr
, "%s: fprintf failed\n", progName
);
138 outputPQGVerify(PQGVerify
* pqgVerify
, PRBool output_binary
, PRBool output_raw
,
141 SECStatus rv
= SECSuccess
;
144 unsigned int counter
;
146 rv
= PK11_PQG_GetHFromVerify(pqgVerify
, &item
);
148 SECU_PrintError(progName
, "PK11_PQG_GetHFromVerify");
151 SECU_PrintInteger(outFile
, &item
, "h", 1);
152 SECITEM_FreeItem(&item
, PR_FALSE
);
154 rv
= PK11_PQG_GetSeedFromVerify(pqgVerify
, &item
);
156 SECU_PrintError(progName
, "PK11_PQG_GetSeedFromVerify");
159 SECU_PrintInteger(outFile
, &item
, "SEED", 1);
160 fprintf(outFile
, " g: %d\n", item
.len
* BPB
);
161 SECITEM_FreeItem(&item
, PR_FALSE
);
163 counter
= PK11_PQG_GetCounterFromVerify(pqgVerify
);
164 fprintf(outFile
, " counter: %d\n", counter
);
165 fprintf(outFile
, "\n");
171 main(int argc
, char **argv
)
173 FILE * outFile
= NULL
;
174 char * outFileName
= NULL
;
175 PQGParams
* pqgParams
= NULL
;
176 PQGVerify
* pqgVerify
= NULL
;
177 int keySizeInBits
= 1024;
183 SECStatus passed
= 0;
184 PRBool output_ascii
= PR_FALSE
;
185 PRBool output_binary
= PR_FALSE
;
186 PRBool output_raw
= PR_FALSE
;
187 PLOptState
*optstate
;
191 progName
= strrchr(argv
[0], '/');
193 progName
= strrchr(argv
[0], '\\');
194 progName
= progName
? progName
+1 : argv
[0];
196 /* Parse command line arguments */
197 optstate
= PL_CreateOptState(argc
, argv
, "?abg:l:n:o:r" );
198 while ((status
= PL_GetNextOpt(optstate
)) == PL_OPT_OK
) {
199 switch (optstate
->option
) {
202 keySizeInBits
= atoi(optstate
->value
);
206 qSizeInBits
= atoi(optstate
->value
);
210 output_ascii
= PR_TRUE
;
214 output_binary
= PR_TRUE
;
218 output_raw
= PR_TRUE
;
223 PORT_Free(outFileName
);
225 outFileName
= PORT_Strdup(optstate
->value
);
232 g
= atoi(optstate
->value
);
243 PL_DestroyOptState(optstate
);
245 if (status
== PL_OPT_BAD
) {
249 /* exactly 1 of these options must be set. */
250 if (1 != ((output_ascii
!= PR_FALSE
) +
251 (output_binary
!= PR_FALSE
) +
252 (output_raw
!= PR_FALSE
))) {
256 gMax
= 2*keySizeInBits
;
257 if (keySizeInBits
< 1024) {
258 j
= PQG_PBITS_TO_INDEX(keySizeInBits
);
260 fprintf(stderr
, "%s: Illegal prime length, \n"
261 "\tacceptable values are between 512 and 1024,\n"
262 "\tand divisible by 64, or 2048 or 3072\n",
267 if ((qSizeInBits
!= 0) && (qSizeInBits
!= 160)) {
268 fprintf(stderr
, "%s: Illegal subprime length, \n"
269 "\tonly 160 is acceptible for primes <= 1024\n",
273 /* this forces keysizes less than 1024 into the DSA1 generation
274 * code. Whether 1024 uses DSA2 or not is triggered by qSizeInBits
275 * being non-zero. All larger keysizes will use DSA2.
279 if (g
!= 0 && (g
< 160 || g
>= gMax
|| g
% 8 != 0)) {
280 fprintf(stderr
, "%s: Illegal g bits, \n"
281 "\tacceptable values are between 160 and %d,\n"
282 "\tand divisible by 8\n", progName
, gMax
);
286 if (!rv
&& outFileName
) {
287 outFile
= fopen(outFileName
, output_binary
? "wb" : "w");
289 fprintf(stderr
, "%s: unable to open \"%s\" for writing\n",
290 progName
, outFileName
);
295 PORT_Free(outFileName
);
301 if (outFile
== NULL
) {
308 if (keySizeInBits
> 1024 || qSizeInBits
!= 0) {
309 rv
= PK11_PQG_ParamGenV2((unsigned)keySizeInBits
,
310 (unsigned) qSizeInBits
, (unsigned)(g
/8), &pqgParams
, &pqgVerify
);
312 rv
= PK11_PQG_ParamGenSeedLen((unsigned)j
, (unsigned)(g
/8),
313 &pqgParams
, &pqgVerify
);
315 rv
= PK11_PQG_ParamGen((unsigned)j
, &pqgParams
, &pqgVerify
);
317 /* below here, must go to loser */
319 if (rv
!= SECSuccess
|| pqgParams
== NULL
|| pqgVerify
== NULL
) {
320 SECU_PrintError(progName
, "PQG parameter generation failed.\n");
323 fprintf(stderr
, "%s: PQG parameter generation completed.\n", progName
);
325 rv
= outputPQGParams(pqgParams
, output_binary
, output_raw
, outFile
);
327 fprintf(stderr
, "%s: failed to output PQG params.\n", progName
);
330 rv
= outputPQGVerify(pqgVerify
, output_binary
, output_raw
, outFile
);
332 fprintf(stderr
, "%s: failed to output PQG Verify.\n", progName
);
336 rv
= PK11_PQG_VerifyParams(pqgParams
, pqgVerify
, &passed
);
337 if (rv
!= SECSuccess
) {
338 fprintf(stderr
, "%s: PQG parameter verification aborted.\n", progName
);
341 if (passed
!= SECSuccess
) {
342 fprintf(stderr
, "%s: PQG parameters failed verification.\n", progName
);
345 fprintf(stderr
, "%s: PQG parameters passed verification.\n", progName
);
347 PK11_PQG_DestroyParams(pqgParams
);
348 PK11_PQG_DestroyVerify(pqgVerify
);
352 PK11_PQG_DestroyParams(pqgParams
);
353 PK11_PQG_DestroyVerify(pqgVerify
);