New option SSL_OP_NO_COMP to disable compression. New ctrls to set
[openssl.git] / apps / ca.c
index 7d10d825b14a08c0a76a987aae5c13948de2f2ad..210b5e1ff47405e3f1141f4d443776264e5b7558 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
 
 #define ENV_DEFAULT_CA         "default_ca"
 
+#define STRING_MASK    "string_mask"
+#define UTF8_IN                        "utf8"
+
 #define ENV_DIR                        "dir"
 #define ENV_CERTS              "certs"
 #define ENV_CRL_DIR            "crl_dir"
 #define ENV_NAMEOPT            "name_opt"
 #define ENV_CERTOPT            "cert_opt"
 #define ENV_EXTCOPY            "copy_extensions"
+#define ENV_UNIQUE_SUBJECT     "unique_subject"
 
 #define ENV_DATABASE           "database"
 
 #define REV_KEY_COMPROMISE     3       /* Value is cert key compromise time */
 #define REV_CA_COMPROMISE      4       /* Value is CA key compromise time */
 
-static char *ca_usage[]={
+static const char *ca_usage[]={
 "usage: ca args\n",
 "\n",
 " -verbose        - Talk alot while doing things\n",
@@ -173,6 +177,7 @@ static char *ca_usage[]={
 " -msie_hack      - msie modifications to handle all those universal strings\n",
 " -revoke file    - Revoke a certificate (given in file)\n",
 " -subj arg       - Use arg instead of request's subject\n",
+" -utf8           - input characters are UTF8 (default ASCII)\n",
 " -multivalue-rdn - enable support for multivalued RDNs\n",
 " -extensions ..  - Extension section (override value in config file)\n",
 " -extfile file   - Configuration file with X509v3 extentions to add\n",
@@ -191,30 +196,30 @@ extern int EF_PROTECT_BELOW;
 extern int EF_ALIGNMENT;
 #endif
 
-static void lookup_fail(char *name,char *tag);
+static void lookup_fail(const char *name, const char *tag);
 static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
                   const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,CA_DB *db,
-                  BIGNUM *serial, char *subj, int multirdn, int email_dn, char *startdate,
+                  BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate,
                   char *enddate, long days, int batch, char *ext_sect, CONF *conf,
                   int verbose, unsigned long certopt, unsigned long nameopt,
                   int default_op, int ext_copy, int selfsign);
 static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
                        const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
-                       CA_DB *db, BIGNUM *serial, char *subj, int multirdn, int email_dn,
+                       CA_DB *db, BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn,
                        char *startdate, char *enddate, long days, int batch,
                        char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
                        unsigned long nameopt, int default_op, int ext_copy,
                        ENGINE *e);
 static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
                         const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
-                        CA_DB *db, BIGNUM *serial,char *subj, int multirdn, int email_dn,
+                        CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn, int email_dn,
                         char *startdate, char *enddate, long days, char *ext_sect,
                         CONF *conf, int verbose, unsigned long certopt, 
                         unsigned long nameopt, int default_op, int ext_copy);
 static int fix_data(int nid, int *type);
 static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
-       STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj, int multirdn,
+       STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn,
        int email_dn, char *startdate, char *enddate, long days, int batch,
                int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
        unsigned long certopt, unsigned long nameopt, int default_op,
@@ -224,7 +229,7 @@ static int get_certificate_status(const char *ser_status, CA_DB *db);
 static int do_updatedb(CA_DB *db);
 static int check_time_format(char *str);
 char *make_revocation_str(int rev_type, char *rev_arg);
-int make_revoked(X509_REVOKED *rev, char *str);
+int make_revoked(X509_REVOKED *rev, const char *str);
 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
 static CONF *conf=NULL;
 static CONF *extconf=NULL;
@@ -240,6 +245,7 @@ int MAIN(int argc, char **argv)
        {
        ENGINE *e = NULL;
        char *key=NULL,*passargin=NULL;
+       int create_ser = 0;
        int free_key = 0;
        int total=0;
        int total_done=0;
@@ -273,6 +279,7 @@ int MAIN(int argc, char **argv)
        char *extensions=NULL;
        char *extfile=NULL;
        char *subj=NULL;
+       unsigned long chtype = MBSTRING_ASC;
        int multirdn = 0;
        char *tmp_email_dn=NULL;
        char *crl_ext=NULL;
@@ -298,7 +305,8 @@ int MAIN(int argc, char **argv)
        X509_REVOKED *r=NULL;
        ASN1_TIME *tmptm;
        ASN1_INTEGER *tmpser;
-       char **pp,*p,*f;
+       char *f;
+       const char *p, **pp;
        int i,j;
        const EVP_MD *dgst=NULL;
        STACK_OF(CONF_VALUE) *attribs=NULL;
@@ -353,6 +361,10 @@ EF_ALIGNMENT=0;
                        subj= *(++argv);
                        /* preserve=1; */
                        }
+               else if (strcmp(*argv,"-utf8") == 0)
+                       chtype = MBSTRING_UTF8;
+               else if (strcmp(*argv,"-create_serial") == 0)
+                       create_ser = 1;
                else if (strcmp(*argv,"-multivalue-rdn") == 0)
                        multirdn=1;
                else if (strcmp(*argv,"-startdate") == 0)
@@ -545,10 +557,6 @@ bad:
 
        ERR_load_crypto_strings();
 
-#ifndef OPENSSL_NO_ENGINE
-       e = setup_engine(bio_err, engine, 0);
-#endif
-
        /*****************************************************************/
        tofree=NULL;
        if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
@@ -556,16 +564,19 @@ bad:
        if (configfile == NULL)
                {
                const char *s=X509_get_default_cert_area();
+               size_t len;
 
 #ifdef OPENSSL_SYS_VMS
-               tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE));
+               len = strlen(s)+sizeof(CONFIG_FILE);
+               tofree=OPENSSL_malloc(len);
                strcpy(tofree,s);
 #else
-               tofree=OPENSSL_malloc(strlen(s)+sizeof(CONFIG_FILE)+1);
-               strcpy(tofree,s);
-               strcat(tofree,"/");
+               len = strlen(s)+sizeof(CONFIG_FILE)+1;
+               tofree=OPENSSL_malloc(len);
+               BUF_strlcpy(tofree,s,len);
+               BUF_strlcat(tofree,"/",len);
 #endif
-               strcat(tofree,CONFIG_FILE);
+               BUF_strlcat(tofree,CONFIG_FILE,len);
                configfile=tofree;
                }
 
@@ -590,6 +601,10 @@ bad:
        if (!load_config(bio_err, conf))
                goto err;
 
+#ifndef OPENSSL_NO_ENGINE
+       e = setup_engine(bio_err, engine, 0);
+#endif
+
        /* Lets get the config section we are using */
        if (section == NULL)
                {
@@ -637,32 +652,36 @@ bad:
                ERR_clear_error();
        app_RAND_load_file(randfile, bio_err, 0);
 
+       f = NCONF_get_string(conf, section, STRING_MASK);
+       if (!f)
+               ERR_clear_error();
+
+       if(f && !ASN1_STRING_set_default_mask_asc(f)) {
+               BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
+               goto err;
+       }
+
+       if (chtype != MBSTRING_UTF8){
+               f = NCONF_get_string(conf, section, UTF8_IN);
+               if (!f)
+                       ERR_clear_error();
+               else if (!strcmp(f, "yes"))
+                       chtype = MBSTRING_UTF8;
+       }
+
        db_attr.unique_subject = 1;
-       p = NCONF_get_string(conf, section, "unique_subject");
+       p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
        if (p)
                {
 #ifdef RL_DEBUG
                BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p);
 #endif
-               switch(*p)
-                       {
-               case 'f': /* false */
-               case 'F': /* FALSE */
-               case 'n': /* no */
-               case 'N': /* NO */
-                       db_attr.unique_subject = 0;
-                       break;
-               case 't': /* true */
-               case 'T': /* TRUE */
-               case 'y': /* yes */
-               case 'Y': /* YES */
-               default:
-                       db_attr.unique_subject = 1;
-                       break;
-                       }
+               db_attr.unique_subject = parse_yesno(p,1);
                }
-#ifdef RL_DEBUG
        else
+               ERR_clear_error();
+#ifdef RL_DEBUG
+       if (!p)
                BIO_printf(bio_err, "DEBUG: unique_subject undefined\n", p);
 #endif
 #ifdef RL_DEBUG
@@ -863,7 +882,7 @@ bad:
        /* Lets check some fields */
        for (i=0; i<sk_num(db->db->data); i++)
                {
-               pp=(char **)sk_value(db->db->data,i);
+               pp=(const char **)sk_value(db->db->data,i);
                if ((pp[DB_type][0] != DB_TYPE_REV) &&
                        (pp[DB_rev_date][0] != '\0'))
                        {
@@ -876,7 +895,7 @@ bad:
                        BIO_printf(bio_err," in entry %d\n", i+1);
                        goto err;
                        }
-               if (!check_time_format(pp[DB_exp_date]))
+               if (!check_time_format((char *)pp[DB_exp_date]))
                        {
                        BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
                        goto err;
@@ -950,7 +969,6 @@ bad:
                        if (verbose) BIO_printf(bio_err,
                                "Done. %d entries marked as expired\n",i); 
                        }
-                       goto err;
                }
 
        /*****************************************************************/
@@ -1001,25 +1019,27 @@ bad:
                        }
                }
 
+       if ((md == NULL) && ((md=NCONF_get_string(conf,
+               section,ENV_DEFAULT_MD)) == NULL))
+               {
+               lookup_fail(section,ENV_DEFAULT_MD);
+               goto err;
+               }
+
+       if ((dgst=EVP_get_digestbyname(md)) == NULL)
+               {
+               BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
+               goto err;
+               }
+
        if (req)
                {
-               if ((md == NULL) && ((md=NCONF_get_string(conf,
-                       section,ENV_DEFAULT_MD)) == NULL))
-                       {
-                       lookup_fail(section,ENV_DEFAULT_MD);
-                       goto err;
-                       }
                if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
                        section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
                        {
                        if(strcmp(tmp_email_dn,"no") == 0)
                                email_dn=0;
                        }
-               if ((dgst=EVP_get_digestbyname(md)) == NULL)
-                       {
-                       BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
-                       goto err;
-                       }
                if (verbose)
                        BIO_printf(bio_err,"message digest is %s\n",
                                OBJ_nid2ln(dgst->type));
@@ -1106,7 +1126,7 @@ bad:
                        goto err;
                        }
 
-               if ((serial=load_serial(serialfile, 0, NULL)) == NULL)
+               if ((serial=load_serial(serialfile, create_ser, NULL)) == NULL)
                        {
                        BIO_printf(bio_err,"error while loading serial number\n");
                        goto err;
@@ -1138,7 +1158,7 @@ bad:
                        {
                        total++;
                        j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
-                               serial,subj,multirdn,email_dn,startdate,enddate,days,extensions,
+                               serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,extensions,
                                conf,verbose,certopt,nameopt,default_op,ext_copy);
                        if (j < 0) goto err;
                        if (j > 0)
@@ -1162,7 +1182,7 @@ bad:
                        {
                        total++;
                        j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
-                               db,serial,subj,multirdn,email_dn,startdate,enddate,days,batch,
+                               db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
                                extensions,conf,verbose, certopt, nameopt,
                                default_op, ext_copy, e);
                        if (j < 0) goto err;
@@ -1182,7 +1202,7 @@ bad:
                        {
                        total++;
                        j=certify(&x,infile,pkey,x509p,dgst,attribs,db,
-                               serial,subj,multirdn,email_dn,startdate,enddate,days,batch,
+                               serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
                                extensions,conf,verbose, certopt, nameopt,
                                default_op, ext_copy, selfsign);
                        if (j < 0) goto err;
@@ -1202,7 +1222,7 @@ bad:
                        {
                        total++;
                        j=certify(&x,argv[i],pkey,x509p,dgst,attribs,db,
-                               serial,subj,multirdn,email_dn,startdate,enddate,days,batch,
+                               serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
                                extensions,conf,verbose, certopt, nameopt,
                                default_op, ext_copy, selfsign);
                        if (j < 0) goto err;
@@ -1250,12 +1270,12 @@ bad:
                for (i=0; i<sk_X509_num(cert_sk); i++)
                        {
                        int k;
-                       unsigned char *n;
+                       char *n;
 
                        x=sk_X509_value(cert_sk,i);
 
                        j=x->cert_info->serialNumber->length;
-                       p=(char *)x->cert_info->serialNumber->data;
+                       p=(const char *)x->cert_info->serialNumber->data;
                        
                        if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
                                {
@@ -1266,15 +1286,19 @@ bad:
                        strcpy(buf[2],outdir);
 
 #ifndef OPENSSL_SYS_VMS
-                       strcat(buf[2],"/");
+                       BUF_strlcat(buf[2],"/",sizeof(buf[2]));
 #endif
 
-                       n=(unsigned char *)&(buf[2][strlen(buf[2])]);
+                       n=(char *)&(buf[2][strlen(buf[2])]);
                        if (j > 0)
                                {
                                for (k=0; k<j; k++)
                                        {
-                                       sprintf((char *)n,"%02X",(unsigned char)*(p++));
+                                       if (n >= &(buf[2][sizeof(buf[2])]))
+                                               break;
+                                       BIO_snprintf(n,
+                                                    &buf[2][0] + sizeof(buf[2]) - n,
+                                                    "%02X",(unsigned char)*(p++));
                                        n+=2;
                                        }
                                }
@@ -1372,7 +1396,7 @@ bad:
 
                for (i=0; i<sk_num(db->db->data); i++)
                        {
-                       pp=(char **)sk_value(db->db->data,i);
+                       pp=(const char **)sk_value(db->db->data,i);
                        if (pp[DB_type][0] == DB_TYPE_REV)
                                {
                                if ((r=X509_REVOKED_new()) == NULL) goto err;
@@ -1398,28 +1422,15 @@ bad:
 
                /* we now have a CRL */
                if (verbose) BIO_printf(bio_err,"signing CRL\n");
-               if (md != NULL)
-                       {
-                       if ((dgst=EVP_get_digestbyname(md)) == NULL)
-                               {
-                               BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
-                               goto err;
-                               }
-                       }
-               else
-                       {
 #ifndef OPENSSL_NO_DSA
-                       if (pkey->type == EVP_PKEY_DSA) 
-                               dgst=EVP_dss1();
-                       else
+               if (pkey->type == EVP_PKEY_DSA) 
+                       dgst=EVP_dss1();
+               else
 #endif
 #ifndef OPENSSL_NO_ECDSA
-                       if (pkey->type == EVP_PKEY_EC)
-                               dgst=EVP_ecdsa();
-                       else
+               if (pkey->type == EVP_PKEY_EC)
+                       dgst=EVP_ecdsa();
 #endif
-                               dgst=EVP_md5();
-                       }
 
                /* Add any extensions asked for */
 
@@ -1514,14 +1525,14 @@ err:
        OPENSSL_EXIT(ret);
        }
 
-static void lookup_fail(char *name, char *tag)
+static void lookup_fail(const char *name, const char *tag)
        {
        BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
        }
 
 static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
             const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
-            BIGNUM *serial, char *subj, int multirdn, int email_dn, char *startdate, char *enddate,
+            BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
             long days, int batch, char *ext_sect, CONF *lconf, int verbose,
             unsigned long certopt, unsigned long nameopt, int default_op,
             int ext_copy, int selfsign)
@@ -1577,7 +1588,7 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
        else
                BIO_printf(bio_err,"Signature ok\n");
 
-       ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, multirdn, email_dn,
+       ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn, email_dn,
                startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
                certopt, nameopt, default_op, ext_copy, selfsign);
 
@@ -1589,7 +1600,7 @@ err:
 
 static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
             const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
-            BIGNUM *serial, char *subj, int multirdn, int email_dn, char *startdate, char *enddate,
+            BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
             long days, int batch, char *ext_sect, CONF *lconf, int verbose,
             unsigned long certopt, unsigned long nameopt, int default_op,
             int ext_copy, ENGINE *e)
@@ -1631,7 +1642,7 @@ static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
        if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
                goto err;
 
-       ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,multirdn,email_dn,startdate,enddate,
+       ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
                days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
                ext_copy, 0);
 
@@ -1643,7 +1654,7 @@ err:
 
 static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
             STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
-            int multirdn,
+            unsigned long chtype, int multirdn,
             int email_dn, char *startdate, char *enddate, long days, int batch,
             int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
             unsigned long certopt, unsigned long nameopt, int default_op,
@@ -1659,7 +1670,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
        X509_NAME_ENTRY *tne,*push;
        EVP_PKEY *pktmp;
        int ok= -1,i,j,last,nid;
-       char *p;
+       const char *p;
        CONF_VALUE *cv;
        char *row[DB_NUMBER],**rrow=NULL,**irow=NULL;
        char buf[25];
@@ -1676,7 +1687,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
 
        if (subj)
                {
-               X509_NAME *n = parse_name(subj, MBSTRING_ASC, multirdn);
+               X509_NAME *n = parse_name(subj, chtype, multirdn);
 
                if (!n)
                        {
@@ -2141,7 +2152,7 @@ again2:
                BIO_printf(bio_err,"Memory allocation failure\n");
                goto err;
                }
-       strcpy(row[DB_file],"unknown");
+       BUF_strlcpy(row[DB_file],"unknown",8);
        row[DB_type][0]='V';
        row[DB_type][1]='\0';
 
@@ -2213,7 +2224,7 @@ static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
 
 static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
             const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
-            BIGNUM *serial, char *subj, int multirdn, int email_dn, char *startdate, char *enddate,
+            BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
             long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
             unsigned long nameopt, int default_op, int ext_copy)
        {
@@ -2354,7 +2365,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
 
        X509_REQ_set_pubkey(req,pktmp);
        EVP_PKEY_free(pktmp);
-       ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,multirdn,email_dn,startdate,enddate,
+       ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
                   days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
                        ext_copy, 0);
 err:
@@ -2442,7 +2453,7 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
                        BIO_printf(bio_err,"Memory allocation failure\n");
                        goto err;
                        }
-               strcpy(row[DB_file],"unknown");
+               BUF_strlcpy(row[DB_file],"unknown",8);
                row[DB_type][0]='V';
                row[DB_type][1]='\0';
 
@@ -2667,7 +2678,7 @@ err:
        return (cnt);
        }
 
-static char *crl_reasons[] = {
+static const char *crl_reasons[] = {
        /* CRL reason strings */
        "unspecified",
        "keyCompromise",
@@ -2695,7 +2706,8 @@ static char *crl_reasons[] = {
 
 char *make_revocation_str(int rev_type, char *rev_arg)
        {
-       char *reason = NULL, *other = NULL, *str;
+       char *other = NULL, *str;
+       const char *reason = NULL;
        ASN1_OBJECT *otmp;
        ASN1_UTCTIME *revtm = NULL;
        int i;
@@ -2766,16 +2778,16 @@ char *make_revocation_str(int rev_type, char *rev_arg)
 
        if (!str) return NULL;
 
-       strcpy(str, (char *)revtm->data);
+       BUF_strlcpy(str, (char *)revtm->data, i);
        if (reason)
                {
-               strcat(str, ",");
-               strcat(str, reason);
+               BUF_strlcat(str, ",", i);
+               BUF_strlcat(str, reason, i);
                }
        if (other)
                {
-               strcat(str, ",");
-               strcat(str, other);
+               BUF_strlcat(str, ",", i);
+               BUF_strlcat(str, other, i);
                }
        ASN1_UTCTIME_free(revtm);
        return str;
@@ -2789,7 +2801,7 @@ char *make_revocation_str(int rev_type, char *rev_arg)
  */
 
 
-int make_revoked(X509_REVOKED *rev, char *str)
+int make_revoked(X509_REVOKED *rev, const char *str)
        {
        char *tmp = NULL;
        int reason_code = -1;
@@ -2882,7 +2894,7 @@ int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
        return 1;
        }
 
-int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
+int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str)
        {
        char *tmp = NULL;
        char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;