155714Skris/* apps/rsa.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296341Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296341Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296341Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296341Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296341Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296341Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
59160814Ssimon#include <openssl/opensslconf.h>
60109998Smarkm#ifndef OPENSSL_NO_RSA
61296341Sdelphij# include <stdio.h>
62296341Sdelphij# include <stdlib.h>
63296341Sdelphij# include <string.h>
64296341Sdelphij# include <time.h>
65296341Sdelphij# include "apps.h"
66296341Sdelphij# include <openssl/bio.h>
67296341Sdelphij# include <openssl/err.h>
68296341Sdelphij# include <openssl/rsa.h>
69296341Sdelphij# include <openssl/evp.h>
70296341Sdelphij# include <openssl/x509.h>
71296341Sdelphij# include <openssl/pem.h>
72296341Sdelphij# include <openssl/bn.h>
7355714Skris
74296341Sdelphij# undef PROG
75296341Sdelphij# define PROG    rsa_main
7655714Skris
77296341Sdelphij/*-
78296341Sdelphij * -inform arg  - input format - default PEM (one of DER, NET or PEM)
7955714Skris * -outform arg - output format - default PEM
80296341Sdelphij * -in arg      - input file - default stdin
81296341Sdelphij * -out arg     - output file - default stdout
82296341Sdelphij * -des         - encrypt output if PEM format with DES in cbc mode
83296341Sdelphij * -des3        - encrypt output if PEM format
84296341Sdelphij * -idea        - encrypt output if PEM format
85296341Sdelphij * -seed        - encrypt output if PEM format
86296341Sdelphij * -aes128      - encrypt output if PEM format
87296341Sdelphij * -aes192      - encrypt output if PEM format
88296341Sdelphij * -aes256      - encrypt output if PEM format
89162911Ssimon * -camellia128 - encrypt output if PEM format
90162911Ssimon * -camellia192 - encrypt output if PEM format
91162911Ssimon * -camellia256 - encrypt output if PEM format
92296341Sdelphij * -text        - print a text version
93296341Sdelphij * -modulus     - print the RSA key modulus
94296341Sdelphij * -check       - verify key consistency
95296341Sdelphij * -pubin       - Expect a public key in input file.
96296341Sdelphij * -pubout      - Output a public key.
9755714Skris */
9855714Skris
9959191Skrisint MAIN(int, char **);
10059191Skris
10155714Skrisint MAIN(int argc, char **argv)
102296341Sdelphij{
103296341Sdelphij    ENGINE *e = NULL;
104296341Sdelphij    int ret = 1;
105296341Sdelphij    RSA *rsa = NULL;
106296341Sdelphij    int i, badops = 0, sgckey = 0;
107296341Sdelphij    const EVP_CIPHER *enc = NULL;
108296341Sdelphij    BIO *out = NULL;
109296341Sdelphij    int informat, outformat, text = 0, check = 0, noout = 0;
110296341Sdelphij    int pubin = 0, pubout = 0;
111296341Sdelphij    char *infile, *outfile, *prog;
112296341Sdelphij    char *passargin = NULL, *passargout = NULL;
113296341Sdelphij    char *passin = NULL, *passout = NULL;
114296341Sdelphij# ifndef OPENSSL_NO_ENGINE
115296341Sdelphij    char *engine = NULL;
116296341Sdelphij# endif
117296341Sdelphij    int modulus = 0;
11855714Skris
119296341Sdelphij    int pvk_encr = 2;
120238405Sjkim
121296341Sdelphij    apps_startup();
12255714Skris
123296341Sdelphij    if (bio_err == NULL)
124296341Sdelphij        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
125296341Sdelphij            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
12655714Skris
127296341Sdelphij    if (!load_config(bio_err, NULL))
128296341Sdelphij        goto end;
129109998Smarkm
130296341Sdelphij    infile = NULL;
131296341Sdelphij    outfile = NULL;
132296341Sdelphij    informat = FORMAT_PEM;
133296341Sdelphij    outformat = FORMAT_PEM;
13455714Skris
135296341Sdelphij    prog = argv[0];
136296341Sdelphij    argc--;
137296341Sdelphij    argv++;
138296341Sdelphij    while (argc >= 1) {
139296341Sdelphij        if (strcmp(*argv, "-inform") == 0) {
140296341Sdelphij            if (--argc < 1)
141296341Sdelphij                goto bad;
142296341Sdelphij            informat = str2fmt(*(++argv));
143296341Sdelphij        } else if (strcmp(*argv, "-outform") == 0) {
144296341Sdelphij            if (--argc < 1)
145296341Sdelphij                goto bad;
146296341Sdelphij            outformat = str2fmt(*(++argv));
147296341Sdelphij        } else if (strcmp(*argv, "-in") == 0) {
148296341Sdelphij            if (--argc < 1)
149296341Sdelphij                goto bad;
150296341Sdelphij            infile = *(++argv);
151296341Sdelphij        } else if (strcmp(*argv, "-out") == 0) {
152296341Sdelphij            if (--argc < 1)
153296341Sdelphij                goto bad;
154296341Sdelphij            outfile = *(++argv);
155296341Sdelphij        } else if (strcmp(*argv, "-passin") == 0) {
156296341Sdelphij            if (--argc < 1)
157296341Sdelphij                goto bad;
158296341Sdelphij            passargin = *(++argv);
159296341Sdelphij        } else if (strcmp(*argv, "-passout") == 0) {
160296341Sdelphij            if (--argc < 1)
161296341Sdelphij                goto bad;
162296341Sdelphij            passargout = *(++argv);
163296341Sdelphij        }
164296341Sdelphij# ifndef OPENSSL_NO_ENGINE
165296341Sdelphij        else if (strcmp(*argv, "-engine") == 0) {
166296341Sdelphij            if (--argc < 1)
167296341Sdelphij                goto bad;
168296341Sdelphij            engine = *(++argv);
169296341Sdelphij        }
170296341Sdelphij# endif
171296341Sdelphij        else if (strcmp(*argv, "-sgckey") == 0)
172296341Sdelphij            sgckey = 1;
173296341Sdelphij        else if (strcmp(*argv, "-pubin") == 0)
174296341Sdelphij            pubin = 1;
175296341Sdelphij        else if (strcmp(*argv, "-pubout") == 0)
176296341Sdelphij            pubout = 1;
177296341Sdelphij        else if (strcmp(*argv, "-RSAPublicKey_in") == 0)
178296341Sdelphij            pubin = 2;
179296341Sdelphij        else if (strcmp(*argv, "-RSAPublicKey_out") == 0)
180296341Sdelphij            pubout = 2;
181296341Sdelphij        else if (strcmp(*argv, "-pvk-strong") == 0)
182296341Sdelphij            pvk_encr = 2;
183296341Sdelphij        else if (strcmp(*argv, "-pvk-weak") == 0)
184296341Sdelphij            pvk_encr = 1;
185296341Sdelphij        else if (strcmp(*argv, "-pvk-none") == 0)
186296341Sdelphij            pvk_encr = 0;
187296341Sdelphij        else if (strcmp(*argv, "-noout") == 0)
188296341Sdelphij            noout = 1;
189296341Sdelphij        else if (strcmp(*argv, "-text") == 0)
190296341Sdelphij            text = 1;
191296341Sdelphij        else if (strcmp(*argv, "-modulus") == 0)
192296341Sdelphij            modulus = 1;
193296341Sdelphij        else if (strcmp(*argv, "-check") == 0)
194296341Sdelphij            check = 1;
195296341Sdelphij        else if ((enc = EVP_get_cipherbyname(&(argv[0][1]))) == NULL) {
196296341Sdelphij            BIO_printf(bio_err, "unknown option %s\n", *argv);
197296341Sdelphij            badops = 1;
198296341Sdelphij            break;
199296341Sdelphij        }
200296341Sdelphij        argc--;
201296341Sdelphij        argv++;
202296341Sdelphij    }
20355714Skris
204296341Sdelphij    if (badops) {
205296341Sdelphij bad:
206296341Sdelphij        BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
207296341Sdelphij        BIO_printf(bio_err, "where options are\n");
208296341Sdelphij        BIO_printf(bio_err,
209296341Sdelphij                   " -inform arg     input format - one of DER NET PEM\n");
210296341Sdelphij        BIO_printf(bio_err,
211296341Sdelphij                   " -outform arg    output format - one of DER NET PEM\n");
212296341Sdelphij        BIO_printf(bio_err, " -in arg         input file\n");
213296341Sdelphij        BIO_printf(bio_err, " -sgckey         Use IIS SGC key format\n");
214296341Sdelphij        BIO_printf(bio_err,
215296341Sdelphij                   " -passin arg     input file pass phrase source\n");
216296341Sdelphij        BIO_printf(bio_err, " -out arg        output file\n");
217296341Sdelphij        BIO_printf(bio_err,
218296341Sdelphij                   " -passout arg    output file pass phrase source\n");
219296341Sdelphij        BIO_printf(bio_err,
220296341Sdelphij                   " -des            encrypt PEM output with cbc des\n");
221296341Sdelphij        BIO_printf(bio_err,
222296341Sdelphij                   " -des3           encrypt PEM output with ede cbc des using 168 bit key\n");
223296341Sdelphij# ifndef OPENSSL_NO_IDEA
224296341Sdelphij        BIO_printf(bio_err,
225296341Sdelphij                   " -idea           encrypt PEM output with cbc idea\n");
226296341Sdelphij# endif
227296341Sdelphij# ifndef OPENSSL_NO_SEED
228296341Sdelphij        BIO_printf(bio_err,
229296341Sdelphij                   " -seed           encrypt PEM output with cbc seed\n");
230296341Sdelphij# endif
231296341Sdelphij# ifndef OPENSSL_NO_AES
232296341Sdelphij        BIO_printf(bio_err, " -aes128, -aes192, -aes256\n");
233296341Sdelphij        BIO_printf(bio_err,
234296341Sdelphij                   "                 encrypt PEM output with cbc aes\n");
235296341Sdelphij# endif
236296341Sdelphij# ifndef OPENSSL_NO_CAMELLIA
237296341Sdelphij        BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n");
238296341Sdelphij        BIO_printf(bio_err,
239296341Sdelphij                   "                 encrypt PEM output with cbc camellia\n");
240296341Sdelphij# endif
241296341Sdelphij        BIO_printf(bio_err, " -text           print the key in text\n");
242296341Sdelphij        BIO_printf(bio_err, " -noout          don't print key out\n");
243296341Sdelphij        BIO_printf(bio_err, " -modulus        print the RSA key modulus\n");
244296341Sdelphij        BIO_printf(bio_err, " -check          verify key consistency\n");
245296341Sdelphij        BIO_printf(bio_err,
246296341Sdelphij                   " -pubin          expect a public key in input file\n");
247296341Sdelphij        BIO_printf(bio_err, " -pubout         output a public key\n");
248296341Sdelphij# ifndef OPENSSL_NO_ENGINE
249296341Sdelphij        BIO_printf(bio_err,
250296341Sdelphij                   " -engine e       use engine e, possibly a hardware device.\n");
251296341Sdelphij# endif
252296341Sdelphij        goto end;
253296341Sdelphij    }
25455714Skris
255296341Sdelphij    ERR_load_crypto_strings();
25655714Skris
257296341Sdelphij# ifndef OPENSSL_NO_ENGINE
258296341Sdelphij    e = setup_engine(bio_err, engine, 0);
259296341Sdelphij# endif
260109998Smarkm
261296341Sdelphij    if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
262296341Sdelphij        BIO_printf(bio_err, "Error getting passwords\n");
263296341Sdelphij        goto end;
264296341Sdelphij    }
26559191Skris
266296341Sdelphij    if (check && pubin) {
267296341Sdelphij        BIO_printf(bio_err, "Only private keys can be checked\n");
268296341Sdelphij        goto end;
269296341Sdelphij    }
27059191Skris
271296341Sdelphij    out = BIO_new(BIO_s_file());
27255714Skris
273296341Sdelphij    {
274296341Sdelphij        EVP_PKEY *pkey;
27555714Skris
276296341Sdelphij        if (pubin) {
277296341Sdelphij            int tmpformat = -1;
278296341Sdelphij            if (pubin == 2) {
279296341Sdelphij                if (informat == FORMAT_PEM)
280296341Sdelphij                    tmpformat = FORMAT_PEMRSA;
281296341Sdelphij                else if (informat == FORMAT_ASN1)
282296341Sdelphij                    tmpformat = FORMAT_ASN1RSA;
283296341Sdelphij            } else if (informat == FORMAT_NETSCAPE && sgckey)
284296341Sdelphij                tmpformat = FORMAT_IISSGC;
285296341Sdelphij            else
286296341Sdelphij                tmpformat = informat;
287109998Smarkm
288296341Sdelphij            pkey = load_pubkey(bio_err, infile, tmpformat, 1,
289296341Sdelphij                               passin, e, "Public Key");
290296341Sdelphij        } else
291296341Sdelphij            pkey = load_key(bio_err, infile,
292296341Sdelphij                            (informat == FORMAT_NETSCAPE && sgckey ?
293296341Sdelphij                             FORMAT_IISSGC : informat), 1,
294296341Sdelphij                            passin, e, "Private Key");
29555714Skris
296296341Sdelphij        if (pkey != NULL)
297296341Sdelphij            rsa = EVP_PKEY_get1_RSA(pkey);
298296341Sdelphij        EVP_PKEY_free(pkey);
299296341Sdelphij    }
30055714Skris
301296341Sdelphij    if (rsa == NULL) {
302296341Sdelphij        ERR_print_errors(bio_err);
303296341Sdelphij        goto end;
304296341Sdelphij    }
30555714Skris
306296341Sdelphij    if (outfile == NULL) {
307296341Sdelphij        BIO_set_fp(out, stdout, BIO_NOCLOSE);
308296341Sdelphij# ifdef OPENSSL_SYS_VMS
309296341Sdelphij        {
310296341Sdelphij            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
311296341Sdelphij            out = BIO_push(tmpbio, out);
312296341Sdelphij        }
313296341Sdelphij# endif
314296341Sdelphij    } else {
315296341Sdelphij        if (BIO_write_filename(out, outfile) <= 0) {
316296341Sdelphij            perror(outfile);
317296341Sdelphij            goto end;
318296341Sdelphij        }
319296341Sdelphij    }
32055714Skris
321296341Sdelphij    if (text)
322296341Sdelphij        if (!RSA_print(out, rsa, 0)) {
323296341Sdelphij            perror(outfile);
324296341Sdelphij            ERR_print_errors(bio_err);
325296341Sdelphij            goto end;
326296341Sdelphij        }
32755714Skris
328296341Sdelphij    if (modulus) {
329296341Sdelphij        BIO_printf(out, "Modulus=");
330296341Sdelphij        BN_print(out, rsa->n);
331296341Sdelphij        BIO_printf(out, "\n");
332296341Sdelphij    }
33355714Skris
334296341Sdelphij    if (check) {
335296341Sdelphij        int r = RSA_check_key(rsa);
33655714Skris
337296341Sdelphij        if (r == 1)
338296341Sdelphij            BIO_printf(out, "RSA key ok\n");
339296341Sdelphij        else if (r == 0) {
340296341Sdelphij            unsigned long err;
34155714Skris
342296341Sdelphij            while ((err = ERR_peek_error()) != 0 &&
343296341Sdelphij                   ERR_GET_LIB(err) == ERR_LIB_RSA &&
344296341Sdelphij                   ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY &&
345296341Sdelphij                   ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) {
346296341Sdelphij                BIO_printf(out, "RSA key error: %s\n",
347296341Sdelphij                           ERR_reason_error_string(err));
348296341Sdelphij                ERR_get_error(); /* remove e from error stack */
349296341Sdelphij            }
350296341Sdelphij        }
35159191Skris
352296341Sdelphij        if (r == -1 || ERR_peek_error() != 0) { /* should happen only if r ==
353296341Sdelphij                                                 * -1 */
354296341Sdelphij            ERR_print_errors(bio_err);
355296341Sdelphij            goto end;
356296341Sdelphij        }
357296341Sdelphij    }
358296341Sdelphij
359296341Sdelphij    if (noout) {
360296341Sdelphij        ret = 0;
361296341Sdelphij        goto end;
362296341Sdelphij    }
363296341Sdelphij    BIO_printf(bio_err, "writing RSA key\n");
364296341Sdelphij    if (outformat == FORMAT_ASN1) {
365296341Sdelphij        if (pubout || pubin) {
366296341Sdelphij            if (pubout == 2)
367296341Sdelphij                i = i2d_RSAPublicKey_bio(out, rsa);
368296341Sdelphij            else
369296341Sdelphij                i = i2d_RSA_PUBKEY_bio(out, rsa);
370296341Sdelphij        } else
371296341Sdelphij            i = i2d_RSAPrivateKey_bio(out, rsa);
372296341Sdelphij    }
373296341Sdelphij# ifndef OPENSSL_NO_RC4
374296341Sdelphij    else if (outformat == FORMAT_NETSCAPE) {
375296341Sdelphij        unsigned char *p, *pp;
376296341Sdelphij        int size;
377296341Sdelphij
378296341Sdelphij        i = 1;
379296341Sdelphij        size = i2d_RSA_NET(rsa, NULL, NULL, sgckey);
380296341Sdelphij        if ((p = (unsigned char *)OPENSSL_malloc(size)) == NULL) {
381296341Sdelphij            BIO_printf(bio_err, "Memory allocation failure\n");
382296341Sdelphij            goto end;
383296341Sdelphij        }
384296341Sdelphij        pp = p;
385296341Sdelphij        i2d_RSA_NET(rsa, &p, NULL, sgckey);
386296341Sdelphij        BIO_write(out, (char *)pp, size);
387296341Sdelphij        OPENSSL_free(pp);
388296341Sdelphij    }
389296341Sdelphij# endif
390296341Sdelphij    else if (outformat == FORMAT_PEM) {
391296341Sdelphij        if (pubout || pubin) {
392296341Sdelphij            if (pubout == 2)
393296341Sdelphij                i = PEM_write_bio_RSAPublicKey(out, rsa);
394296341Sdelphij            else
395296341Sdelphij                i = PEM_write_bio_RSA_PUBKEY(out, rsa);
396296341Sdelphij        } else
397296341Sdelphij            i = PEM_write_bio_RSAPrivateKey(out, rsa,
398296341Sdelphij                                            enc, NULL, 0, NULL, passout);
399296341Sdelphij# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
400296341Sdelphij    } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
401296341Sdelphij        EVP_PKEY *pk;
402296341Sdelphij        pk = EVP_PKEY_new();
403296341Sdelphij        EVP_PKEY_set1_RSA(pk, rsa);
404296341Sdelphij        if (outformat == FORMAT_PVK)
405296341Sdelphij            i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
406296341Sdelphij        else if (pubin || pubout)
407296341Sdelphij            i = i2b_PublicKey_bio(out, pk);
408296341Sdelphij        else
409296341Sdelphij            i = i2b_PrivateKey_bio(out, pk);
410296341Sdelphij        EVP_PKEY_free(pk);
411296341Sdelphij# endif
412296341Sdelphij    } else {
413296341Sdelphij        BIO_printf(bio_err, "bad output format specified for outfile\n");
414296341Sdelphij        goto end;
415296341Sdelphij    }
416296341Sdelphij    if (i <= 0) {
417296341Sdelphij        BIO_printf(bio_err, "unable to write key\n");
418296341Sdelphij        ERR_print_errors(bio_err);
419296341Sdelphij    } else
420296341Sdelphij        ret = 0;
421296341Sdelphij end:
422296341Sdelphij    if (out != NULL)
423296341Sdelphij        BIO_free_all(out);
424296341Sdelphij    if (rsa != NULL)
425296341Sdelphij        RSA_free(rsa);
426296341Sdelphij    if (passin)
427296341Sdelphij        OPENSSL_free(passin);
428296341Sdelphij    if (passout)
429296341Sdelphij        OPENSSL_free(passout);
430296341Sdelphij    apps_shutdown();
431296341Sdelphij    OPENSSL_EXIT(ret);
432296341Sdelphij}
433296341Sdelphij#else                           /* !OPENSSL_NO_RSA */
434296341Sdelphij
43559191Skris# if PEDANTIC
436296341Sdelphijstatic void *dummy = &dummy;
43759191Skris# endif
43859191Skris
43955714Skris#endif
440