" -engine e - use engine e, possibly a hardware device.\n",
#endif
" -certopt arg - various certificate text options\n",
+" -checkhost host - check certificate matches \"host\"\n",
+" -checkemail email - check certificate matches \"email\"\n",
+" -checkip ipaddr - check certificate matches \"ipaddr\"\n",
NULL
};
static int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *digest,
CONF *conf, char *section);
static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
- X509 *x,X509 *xca,EVP_PKEY *pkey,char *serial,
- int create,int days, int clrext, CONF *conf, char *section,
- ASN1_INTEGER *sno);
+ X509 *x,X509 *xca,EVP_PKEY *pkey,
+ STACK_OF(OPENSSL_STRING) *sigopts,
+ char *serial, int create ,int days, int clrext,
+ CONF *conf, char *section, ASN1_INTEGER *sno);
static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
static int reqfile=0;
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+static int force_version=2;
+#endif
int MAIN(int, char **);
X509_REQ *req=NULL;
X509 *x=NULL,*xca=NULL;
ASN1_OBJECT *objtmp;
- EVP_PKEY *Upkey=NULL,*CApkey=NULL;
+ STACK_OF(OPENSSL_STRING) *sigopts = NULL;
+ EVP_PKEY *Upkey=NULL,*CApkey=NULL, *fkey = NULL;
ASN1_INTEGER *sno = NULL;
- int i,num,badops=0;
+ int i,num,badops=0, badsig=0;
BIO *out=NULL;
BIO *STDout=NULL;
STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
int informat,outformat,keyformat,CAformat,CAkeyformat;
char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
char *CAkeyfile=NULL,*CAserial=NULL;
+ char *fkeyfile=NULL;
char *alias=NULL;
int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0;
int next_serial=0;
int need_rand = 0;
int checkend=0,checkoffset=0;
unsigned long nmflag = 0, certflag = 0;
+ char *checkhost = NULL;
+ char *checkemail = NULL;
+ char *checkip = NULL;
#ifndef OPENSSL_NO_ENGINE
char *engine=NULL;
#endif
if (--argc < 1) goto bad;
CAkeyformat=str2fmt(*(++argv));
}
+ else if (strcmp(*argv,"-sigopt") == 0)
+ {
+ if (--argc < 1)
+ goto bad;
+ if (!sigopts)
+ sigopts = sk_OPENSSL_STRING_new_null();
+ if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+ goto bad;
+ }
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+ else if (strcmp(*argv,"-force_version") == 0)
+ {
+ if (--argc < 1) goto bad;
+ force_version=atoi(*(++argv)) - 1;
+ }
+#endif
else if (strcmp(*argv,"-days") == 0)
{
if (--argc < 1) goto bad;
days=atoi(*(++argv));
if (days == 0)
{
- BIO_printf(STDout,"bad number of days\n");
+ BIO_printf(bio_err,"bad number of days\n");
goto bad;
}
}
if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
goto bad;
}
+ else if (strcmp(*argv,"-force_pubkey") == 0)
+ {
+ if (--argc < 1) goto bad;
+ fkeyfile= *(++argv);
+ }
else if (strcmp(*argv,"-addtrust") == 0)
{
if (--argc < 1) goto bad;
checkoffset=atoi(*(++argv));
checkend=1;
}
+ else if (strcmp(*argv,"-checkhost") == 0)
+ {
+ if (--argc < 1) goto bad;
+ checkhost=*(++argv);
+ }
+ else if (strcmp(*argv,"-checkemail") == 0)
+ {
+ if (--argc < 1) goto bad;
+ checkemail=*(++argv);
+ }
+ else if (strcmp(*argv,"-checkip") == 0)
+ {
+ if (--argc < 1) goto bad;
+ checkip=*(++argv);
+ }
else if (strcmp(*argv,"-noout") == 0)
noout= ++num;
else if (strcmp(*argv,"-trustout") == 0)
#endif
else if (strcmp(*argv,"-ocspid") == 0)
ocspid= ++num;
+ else if (strcmp(*argv,"-badsig") == 0)
+ badsig = 1;
else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
{
/* ok */
goto end;
}
+ if (fkeyfile)
+ {
+ fkey = load_pubkey(bio_err, fkeyfile, keyformat, 0,
+ NULL, e, "Forced key");
+ if (fkey == NULL) goto end;
+ }
+
if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM))
{ CAkeyfile=CAfile; }
else if ((CA_flag) && (CAkeyfile == NULL))
X509_gmtime_adj(X509_get_notBefore(x),0);
X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL);
-
- pkey = X509_REQ_get_pubkey(req);
- X509_set_pubkey(x,pkey);
- EVP_PKEY_free(pkey);
+ if (fkey)
+ X509_set_pubkey(x, fkey);
+ else
+ {
+ pkey = X509_REQ_get_pubkey(req);
+ X509_set_pubkey(x,pkey);
+ EVP_PKEY_free(pkey);
+ }
}
else
x=load_cert(bio_err,infile,informat,NULL,e,"Certificate");
}
else if (text == i)
{
- X509_print_ex(out,x,nmflag, certflag);
+ X509_print_ex(STDout,x,nmflag, certflag);
}
else if (startdate == i)
{
assert(need_rand);
if (!x509_certify(ctx,CAfile,digest,x,xca,
- CApkey, CAserial,CA_createserial,days, clrext,
+ CApkey, sigopts,
+ CAserial,CA_createserial,days, clrext,
extconf, extsect, sno))
goto end;
}
else
{
pk=load_key(bio_err,
- keyfile, FORMAT_PEM, 0,
+ keyfile, keyformat, 0,
passin, e, "request key");
if (pk == NULL) goto end;
}
goto end;
}
+ print_cert_checks(STDout, x, checkhost, checkemail, checkip);
+
if (noout)
{
ret=0;
goto end;
}
+ if (badsig)
+ x->signature->data[x->signature->length - 1] ^= 0x1;
+
if (outformat == FORMAT_ASN1)
i=i2d_X509_bio(out,x);
else if (outformat == FORMAT_PEM)
X509_free(xca);
EVP_PKEY_free(Upkey);
EVP_PKEY_free(CApkey);
+ EVP_PKEY_free(fkey);
+ if (sigopts)
+ sk_OPENSSL_STRING_free(sigopts);
X509_REQ_free(rq);
ASN1_INTEGER_free(sno);
sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
}
static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
- X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,
- int days, int clrext, CONF *conf, char *section, ASN1_INTEGER *sno)
+ X509 *x, X509 *xca, EVP_PKEY *pkey,
+ STACK_OF(OPENSSL_STRING) *sigopts,
+ char *serialfile, int create,
+ int days, int clrext, CONF *conf, char *section,
+ ASN1_INTEGER *sno)
{
int ret=0;
ASN1_INTEGER *bs=NULL;
if (conf)
{
X509V3_CTX ctx2;
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+ X509_set_version(x, force_version);
+#else
X509_set_version(x,2); /* version 3 certificate */
+#endif
X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
X509V3_set_nconf(&ctx2, conf);
if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end;
}
- if (!X509_sign(x,pkey,digest)) goto end;
+ if (!do_X509_sign(bio_err, x, pkey, digest, sigopts))
+ goto end;
ret=1;
end:
X509_STORE_CTX_cleanup(&xsc);
if (conf)
{
X509V3_CTX ctx;
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+ X509_set_version(x, force_version);
+#else
X509_set_version(x,2); /* version 3 certificate */
+#endif
X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
X509V3_set_nconf(&ctx, conf);
if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) goto err;