apps/ca.c:1500: error: NULL_DEREFERENCE
  pointer `str` last assigned on line 1493 could be null and is dereferenced at line 1500, column 17.
Showing all 73 steps of the trace


apps/ca.c:1440:1: start of procedure do_body()
1438.   }
1439.   
1440. > static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
1441.                      const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
1442.                      STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,

apps/ca.c:1449:5: 
1447.                      int default_op, int ext_copy, int selfsign)
1448.   {
1449. >     X509_NAME *name = NULL, *CAname = NULL, *subject = NULL, *dn_subject =
1450.           NULL;
1451.       ASN1_UTCTIME *tm, *tmptm;

apps/ca.c:1454:5: 
1452.       ASN1_STRING *str, *str2;
1453.       ASN1_OBJECT *obj;
1454. >     X509 *ret = NULL;
1455.       X509_NAME_ENTRY *ne;
1456.       X509_NAME_ENTRY *tne, *push;

apps/ca.c:1458:5: 
1456.       X509_NAME_ENTRY *tne, *push;
1457.       EVP_PKEY *pktmp;
1458. >     int ok = -1, i, j, last, nid;
1459.       const char *p;
1460.       CONF_VALUE *cv;

apps/ca.c:1462:5: 
1460.       CONF_VALUE *cv;
1461.       OPENSSL_STRING row[DB_NUMBER];
1462. >     OPENSSL_STRING *irow = NULL;
1463.       OPENSSL_STRING *rrow = NULL;
1464.       char buf[25];

apps/ca.c:1463:5: 
1461.       OPENSSL_STRING row[DB_NUMBER];
1462.       OPENSSL_STRING *irow = NULL;
1463. >     OPENSSL_STRING *rrow = NULL;
1464.       char buf[25];
1465.   

apps/ca.c:1466:5: 
1464.       char buf[25];
1465.   
1466. >     tmptm = ASN1_UTCTIME_new();
1467.       if (tmptm == NULL) {
1468.           BIO_printf(bio_err, "malloc error\n");

crypto/asn1/tasn_typ.c:86:1: start of procedure ASN1_UTCTIME_new()
  84.   IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_IA5STRING)
  85.   IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALSTRING)
  86. > IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTCTIME)
  87.   IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALIZEDTIME)
  88.   IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_VISIBLESTRING)

crypto/asn1/tasn_typ.c:86:1: return from a call to ASN1_UTCTIME_new
  84.   IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_IA5STRING)
  85.   IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALSTRING)
  86. > IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTCTIME)
  87.   IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALIZEDTIME)
  88.   IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_VISIBLESTRING)

apps/ca.c:1467:9: Taking false branch
1465.   
1466.       tmptm = ASN1_UTCTIME_new();
1467.       if (tmptm == NULL) {
                ^
1468.           BIO_printf(bio_err, "malloc error\n");
1469.           return (0);

apps/ca.c:1472:10: 
1470.       }
1471.   
1472. >     for (i = 0; i < DB_NUMBER; i++)
1473.           row[i] = NULL;
1474.   

apps/ca.c:1472:17: Loop condition is true. Entering loop body
1470.       }
1471.   
1472.       for (i = 0; i < DB_NUMBER; i++)
                        ^
1473.           row[i] = NULL;
1474.   

apps/ca.c:1473:9: 
1471.   
1472.       for (i = 0; i < DB_NUMBER; i++)
1473. >         row[i] = NULL;
1474.   
1475.       if (subj) {

apps/ca.c:1472:32: 
1470.       }
1471.   
1472. >     for (i = 0; i < DB_NUMBER; i++)
1473.           row[i] = NULL;
1474.   

apps/ca.c:1472:17: Loop condition is false. Leaving loop
1470.       }
1471.   
1472.       for (i = 0; i < DB_NUMBER; i++)
                        ^
1473.           row[i] = NULL;
1474.   

apps/ca.c:1475:9: Taking false branch
1473.           row[i] = NULL;
1474.   
1475.       if (subj) {
                ^
1476.           X509_NAME *n = parse_name(subj, chtype, multirdn);
1477.   

apps/ca.c:1486:9: Taking false branch
1484.       }
1485.   
1486.       if (default_op)
                ^
1487.           BIO_printf(bio_err,
1488.                      "The Subject's Distinguished Name is as follows\n");

apps/ca.c:1490:5: 
1488.                      "The Subject's Distinguished Name is as follows\n");
1489.   
1490. >     name = X509_REQ_get_subject_name(req);
1491.       for (i = 0; i < X509_NAME_entry_count(name); i++) {
1492.           ne = X509_NAME_get_entry(name, i);

crypto/x509/x509_req.c:313:1: start of procedure X509_REQ_get_subject_name()
  311.   }
  312.   
  313. > X509_NAME *X509_REQ_get_subject_name(X509_REQ *req)
  314.   {
  315.       return req->req_info.subject;

crypto/x509/x509_req.c:315:5: 
  313.   X509_NAME *X509_REQ_get_subject_name(X509_REQ *req)
  314.   {
  315. >     return req->req_info.subject;
  316.   }

crypto/x509/x509_req.c:316:1: return from a call to X509_REQ_get_subject_name
  314.   {
  315.       return req->req_info.subject;
  316. > }

apps/ca.c:1491:10: 
1489.   
1490.       name = X509_REQ_get_subject_name(req);
1491. >     for (i = 0; i < X509_NAME_entry_count(name); i++) {
1492.           ne = X509_NAME_get_entry(name, i);
1493.           str = X509_NAME_ENTRY_get_data(ne);

apps/ca.c:1491:17: 
1489.   
1490.       name = X509_REQ_get_subject_name(req);
1491. >     for (i = 0; i < X509_NAME_entry_count(name); i++) {
1492.           ne = X509_NAME_get_entry(name, i);
1493.           str = X509_NAME_ENTRY_get_data(ne);

crypto/x509/x509name.c:96:1: start of procedure X509_NAME_entry_count()
  94.   }
  95.   
  96. > int X509_NAME_entry_count(X509_NAME *name)
  97.   {
  98.       if (name == NULL)

crypto/x509/x509name.c:98:9: Taking false branch
  96.   int X509_NAME_entry_count(X509_NAME *name)
  97.   {
  98.       if (name == NULL)
                 ^
  99.           return (0);
  100.       return (sk_X509_NAME_ENTRY_num(name->entries));

crypto/x509/x509name.c:100:13: Condition is true
  98.       if (name == NULL)
  99.           return (0);
  100.       return (sk_X509_NAME_ENTRY_num(name->entries));
                     ^
  101.   }
  102.   

crypto/x509/x509name.c:100:5: 
  98.       if (name == NULL)
  99.           return (0);
  100. >     return (sk_X509_NAME_ENTRY_num(name->entries));
  101.   }
  102.   

crypto/stack/stack.c:317:1: start of procedure sk_num()
    315.   }
    316.   
    317. > int sk_num(const _STACK *st)
    318.   {
    319.       if (st == NULL)

crypto/stack/stack.c:319:9: Taking false branch
    317.   int sk_num(const _STACK *st)
    318.   {
    319.       if (st == NULL)
                   ^
    320.           return -1;
    321.       return st->num;

crypto/stack/stack.c:321:5: 
    319.       if (st == NULL)
    320.           return -1;
    321. >     return st->num;
    322.   }
    323.   

crypto/stack/stack.c:322:1: return from a call to sk_num
    320.           return -1;
    321.       return st->num;
    322. > }
    323.   
    324.   void *sk_value(const _STACK *st, int i)

crypto/x509/x509name.c:101:1: return from a call to X509_NAME_entry_count
  99.           return (0);
  100.       return (sk_X509_NAME_ENTRY_num(name->entries));
  101. > }
  102.   
  103.   int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)

apps/ca.c:1491:17: Loop condition is true. Entering loop body
1489.   
1490.       name = X509_REQ_get_subject_name(req);
1491.       for (i = 0; i < X509_NAME_entry_count(name); i++) {
                        ^
1492.           ne = X509_NAME_get_entry(name, i);
1493.           str = X509_NAME_ENTRY_get_data(ne);

apps/ca.c:1492:9: 
1490.       name = X509_REQ_get_subject_name(req);
1491.       for (i = 0; i < X509_NAME_entry_count(name); i++) {
1492. >         ne = X509_NAME_get_entry(name, i);
1493.           str = X509_NAME_ENTRY_get_data(ne);
1494.           obj = X509_NAME_ENTRY_get_object(ne);

crypto/x509/x509name.c:134:1: start of procedure X509_NAME_get_entry()
  132.   }
  133.   
  134. > X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
  135.   {
  136.       if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc

crypto/x509/x509name.c:136:9: Taking false branch
  134.   X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
  135.   {
  136.       if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
                 ^
  137.           || loc < 0)
  138.           return (NULL);

crypto/x509/x509name.c:136:25: Condition is true
  134.   X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
  135.   {
  136.       if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
                                 ^
  137.           || loc < 0)
  138.           return (NULL);

crypto/stack/stack.c:317:1: start of procedure sk_num()
    315.   }
    316.   
    317. > int sk_num(const _STACK *st)
    318.   {
    319.       if (st == NULL)

crypto/stack/stack.c:319:9: Taking false branch
    317.   int sk_num(const _STACK *st)
    318.   {
    319.       if (st == NULL)
                   ^
    320.           return -1;
    321.       return st->num;

crypto/stack/stack.c:321:5: 
    319.       if (st == NULL)
    320.           return -1;
    321. >     return st->num;
    322.   }
    323.   

crypto/stack/stack.c:322:1: return from a call to sk_num
    320.           return -1;
    321.       return st->num;
    322. > }
    323.   
    324.   void *sk_value(const _STACK *st, int i)

crypto/x509/x509name.c:136:25: Taking false branch
  134.   X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
  135.   {
  136.       if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
                                 ^
  137.           || loc < 0)
  138.           return (NULL);

crypto/x509/x509name.c:137:12: Taking false branch
  135.   {
  136.       if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
  137.           || loc < 0)
                    ^
  138.           return (NULL);
  139.       else

crypto/x509/x509name.c:140:17: Condition is true
  138.           return (NULL);
  139.       else
  140.           return (sk_X509_NAME_ENTRY_value(name->entries, loc));
                         ^
  141.   }
  142.   

crypto/x509/x509name.c:140:9: 
  138.           return (NULL);
  139.       else
  140. >         return (sk_X509_NAME_ENTRY_value(name->entries, loc));
  141.   }
  142.   

crypto/stack/stack.c:324:1: start of procedure sk_value()
    322.   }
    323.   
    324. > void *sk_value(const _STACK *st, int i)
    325.   {
    326.       if (!st || (i < 0) || (i >= st->num))

crypto/stack/stack.c:326:10: Taking false branch
    324.   void *sk_value(const _STACK *st, int i)
    325.   {
    326.       if (!st || (i < 0) || (i >= st->num))
                    ^
    327.           return NULL;
    328.       return st->data[i];

crypto/stack/stack.c:326:17: Taking false branch
    324.   void *sk_value(const _STACK *st, int i)
    325.   {
    326.       if (!st || (i < 0) || (i >= st->num))
                           ^
    327.           return NULL;
    328.       return st->data[i];

crypto/stack/stack.c:326:28: Taking false branch
    324.   void *sk_value(const _STACK *st, int i)
    325.   {
    326.       if (!st || (i < 0) || (i >= st->num))
                                      ^
    327.           return NULL;
    328.       return st->data[i];

crypto/stack/stack.c:328:5: 
    326.       if (!st || (i < 0) || (i >= st->num))
    327.           return NULL;
    328. >     return st->data[i];
    329.   }
    330.   

crypto/stack/stack.c:329:1: return from a call to sk_value
    327.           return NULL;
    328.       return st->data[i];
    329. > }
    330.   
    331.   void *sk_set(_STACK *st, int i, void *value)

crypto/x509/x509name.c:141:1: return from a call to X509_NAME_get_entry
  139.       else
  140.           return (sk_X509_NAME_ENTRY_value(name->entries, loc));
  141. > }
  142.   
  143.   X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)

apps/ca.c:1493:9: 
1491.       for (i = 0; i < X509_NAME_entry_count(name); i++) {
1492.           ne = X509_NAME_get_entry(name, i);
1493. >         str = X509_NAME_ENTRY_get_data(ne);
1494.           obj = X509_NAME_ENTRY_get_object(ne);
1495.   

crypto/x509/x509name.c:392:1: start of procedure X509_NAME_ENTRY_get_data()
  390.   }
  391.   
  392. > ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
  393.   {
  394.       if (ne == NULL)

crypto/x509/x509name.c:394:9: Taking true branch
  392.   ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
  393.   {
  394.       if (ne == NULL)
                 ^
  395.           return (NULL);
  396.       return (ne->value);

crypto/x509/x509name.c:395:9: 
  393.   {
  394.       if (ne == NULL)
  395. >         return (NULL);
  396.       return (ne->value);
  397.   }

crypto/x509/x509name.c:397:1: return from a call to X509_NAME_ENTRY_get_data
  395.           return (NULL);
  396.       return (ne->value);
  397. > }
  398.   
  399.   int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne)

apps/ca.c:1494:9: 
1492.           ne = X509_NAME_get_entry(name, i);
1493.           str = X509_NAME_ENTRY_get_data(ne);
1494. >         obj = X509_NAME_ENTRY_get_object(ne);
1495.   
1496.           if (msie_hack) {

crypto/x509/x509name.c:385:1: start of procedure X509_NAME_ENTRY_get_object()
  383.   }
  384.   
  385. > ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
  386.   {
  387.       if (ne == NULL)

crypto/x509/x509name.c:387:9: Taking true branch
  385.   ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
  386.   {
  387.       if (ne == NULL)
                 ^
  388.           return (NULL);
  389.       return (ne->object);

crypto/x509/x509name.c:388:9: 
  386.   {
  387.       if (ne == NULL)
  388. >         return (NULL);
  389.       return (ne->object);
  390.   }

crypto/x509/x509name.c:390:1: return from a call to X509_NAME_ENTRY_get_object
  388.           return (NULL);
  389.       return (ne->object);
  390. > }
  391.   
  392.   ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)

apps/ca.c:1496:13: Taking true branch
1494.           obj = X509_NAME_ENTRY_get_object(ne);
1495.   
1496.           if (msie_hack) {
                    ^
1497.               /* assume all type should be strings */
1498.               nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));

apps/ca.c:1498:13: 
1496.           if (msie_hack) {
1497.               /* assume all type should be strings */
1498. >             nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));
1499.   
1500.               if (str->type == V_ASN1_UNIVERSALSTRING)

crypto/x509/x509name.c:385:1: start of procedure X509_NAME_ENTRY_get_object()
  383.   }
  384.   
  385. > ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
  386.   {
  387.       if (ne == NULL)

crypto/x509/x509name.c:387:9: Taking true branch
  385.   ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
  386.   {
  387.       if (ne == NULL)
                 ^
  388.           return (NULL);
  389.       return (ne->object);

crypto/x509/x509name.c:388:9: 
  386.   {
  387.       if (ne == NULL)
  388. >         return (NULL);
  389.       return (ne->object);
  390.   }

crypto/x509/x509name.c:390:1: return from a call to X509_NAME_ENTRY_get_object
  388.           return (NULL);
  389.       return (ne->object);
  390. > }
  391.   
  392.   ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)

crypto/objects/obj_dat.c:390:1: start of procedure OBJ_obj2nid()
  388.   IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
  389.   
  390. > int OBJ_obj2nid(const ASN1_OBJECT *a)
  391.   {
  392.       const unsigned int *op;

crypto/objects/obj_dat.c:395:9: Taking true branch
  393.       ADDED_OBJ ad, *adp;
  394.   
  395.       if (a == NULL)
                 ^
  396.           return (NID_undef);
  397.       if (a->nid != 0)

crypto/objects/obj_dat.c:396:9: 
  394.   
  395.       if (a == NULL)
  396. >         return (NID_undef);
  397.       if (a->nid != 0)
  398.           return (a->nid);

crypto/objects/obj_dat.c:414:1: return from a call to OBJ_obj2nid
  412.           return (NID_undef);
  413.       return (nid_objs[*op].nid);
  414. > }
  415.   
  416.   /*

apps/ca.c:1500:17: 
1498.               nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));
1499.   
1500. >             if (str->type == V_ASN1_UNIVERSALSTRING)
1501.                   ASN1_UNIVERSALSTRING_to_string(str);
1502.   

static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
                   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 *lconf, unsigned long certopt, unsigned long nameopt,
                   int default_op, int ext_copy, int selfsign)
{
    X509_NAME *name = NULL, *CAname = NULL, *subject = NULL, *dn_subject =
        NULL;
    ASN1_UTCTIME *tm, *tmptm;
    ASN1_STRING *str, *str2;
    ASN1_OBJECT *obj;
    X509 *ret = NULL;
    X509_NAME_ENTRY *ne;
    X509_NAME_ENTRY *tne, *push;
    EVP_PKEY *pktmp;
    int ok = -1, i, j, last, nid;
    const char *p;
    CONF_VALUE *cv;
    OPENSSL_STRING row[DB_NUMBER];
    OPENSSL_STRING *irow = NULL;
    OPENSSL_STRING *rrow = NULL;
    char buf[25];
    tmptm = ASN1_UTCTIME_new();
    if (tmptm == NULL) {
        BIO_printf(bio_err, "malloc error\n");
        return (0);
    }
    for (i = 0; i < DB_NUMBER; i++)
        row[i] = NULL;
    if (subj) {
        X509_NAME *n = parse_name(subj, chtype, multirdn);
        if (!n) {
            ERR_print_errors(bio_err);
            goto end;
        }
        X509_REQ_set_subject_name(req, n);
        X509_NAME_free(n);
    }
    if (default_op)
        BIO_printf(bio_err,
                   "The Subject's Distinguished Name is as follows\n");
    name = X509_REQ_get_subject_name(req);
    for (i = 0; i < X509_NAME_entry_count(name); i++) {
        ne = X509_NAME_get_entry(name, i);
        str = X509_NAME_ENTRY_get_data(ne);
        obj = X509_NAME_ENTRY_get_object(ne);
        if (msie_hack) {
            nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));
            if (str->type == V_ASN1_UNIVERSALSTRING)
                ASN1_UNIVERSALSTRING_to_string(str);
            if ((str->type == V_ASN1_IA5STRING) &&
                (nid != NID_pkcs9_emailAddress))
                str->type = V_ASN1_T61STRING;
            if ((nid == NID_pkcs9_emailAddress) &&
                (str->type == V_ASN1_PRINTABLESTRING))
                str->type = V_ASN1_IA5STRING;
        }
        if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
            continue;
        if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
            (str->type != V_ASN1_IA5STRING)) {
            BIO_printf(bio_err,
                       "\nemailAddress type needs to be of type IA5STRING\n");
            goto end;
        }
        if ((str->type != V_ASN1_BMPSTRING)
            && (str->type != V_ASN1_UTF8STRING)) {
            j = ASN1_PRINTABLE_type(str->data, str->length);
            if (((j == V_ASN1_T61STRING) &&
                 (str->type != V_ASN1_T61STRING)) ||
                ((j == V_ASN1_IA5STRING) &&
                 (str->type == V_ASN1_PRINTABLESTRING))) {
                BIO_printf(bio_err,
                           "\nThe string contains characters that are illegal for the ASN.1 type\n");
                goto end;
            }
        }
        if (default_op)
            old_entry_print(obj, str);
    }
    if ((subject = X509_NAME_new()) == NULL) {
        BIO_printf(bio_err, "Memory allocation failure\n");
        goto end;
    }
    if (selfsign)
        CAname = X509_NAME_dup(name);
    else
        CAname = X509_NAME_dup(X509_get_subject_name(x509));
    if (CAname == NULL)
        goto end;
    str = str2 = NULL;
    for (i = 0; i < sk_CONF_VALUE_num(policy); i++) {
        cv = sk_CONF_VALUE_value(policy, i);
        if ((j = OBJ_txt2nid(cv->name)) == NID_undef) {
            BIO_printf(bio_err,
                       "%s:unknown object type in 'policy' configuration\n",
                       cv->name);
            goto end;
        }
        obj = OBJ_nid2obj(j);
        last = -1;
        for (;;) {
            j = X509_NAME_get_index_by_OBJ(name, obj, last);
            if (j < 0) {
                if (last != -1)
                    break;
                tne = NULL;
            } else {
                tne = X509_NAME_get_entry(name, j);
            }
            last = j;
            push = NULL;
            if (strcmp(cv->value, "optional") == 0) {
                if (tne != NULL)
                    push = tne;
            } else if (strcmp(cv->value, "supplied") == 0) {
                if (tne == NULL) {
                    BIO_printf(bio_err,
                               "The %s field needed to be supplied and was missing\n",
                               cv->name);
                    goto end;
                } else
                    push = tne;
            } else if (strcmp(cv->value, "match") == 0) {
                int last2;
                if (tne == NULL) {
                    BIO_printf(bio_err,
                               "The mandatory %s field was missing\n",
                               cv->name);
                    goto end;
                }
                last2 = -1;
 again2:
                j = X509_NAME_get_index_by_OBJ(CAname, obj, last2);
                if ((j < 0) && (last2 == -1)) {
                    BIO_printf(bio_err,
                               "The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",
                               cv->name);
                    goto end;
                }
                if (j >= 0) {
                    push = X509_NAME_get_entry(CAname, j);
                    str = X509_NAME_ENTRY_get_data(tne);
                    str2 = X509_NAME_ENTRY_get_data(push);
                    last2 = j;
                    if (ASN1_STRING_cmp(str, str2) != 0)
                        goto again2;
                }
                if (j < 0) {
                    BIO_printf(bio_err,
                               "The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",
                               cv->name,
                               ((str2 == NULL) ? "NULL" : (char *)str2->data),
                               ((str == NULL) ? "NULL" : (char *)str->data));
                    goto end;
                }
            } else {
                BIO_printf(bio_err,
                           "%s:invalid type in 'policy' configuration\n",
                           cv->value);
                goto end;
            }
            if (push != NULL) {
                if (!X509_NAME_add_entry(subject, push, -1, 0)) {
                    X509_NAME_ENTRY_free(push);
                    BIO_printf(bio_err, "Memory allocation failure\n");
                    goto end;
                }
            }
            if (j < 0)
                break;
        }
    }
    if (preserve) {
        X509_NAME_free(subject);
        subject = X509_NAME_dup(name);
        if (subject == NULL)
            goto end;
    }
    if (verbose)
        BIO_printf(bio_err,
                   "The subject name appears to be ok, checking data base for clashes\n");
    if (email_dn)
        dn_subject = subject;
    else {
        X509_NAME_ENTRY *tmpne;
        if ((dn_subject = X509_NAME_dup(subject)) == NULL) {
            BIO_printf(bio_err, "Memory allocation failure\n");
            goto end;
        }
        while ((i = X509_NAME_get_index_by_NID(dn_subject,
                                               NID_pkcs9_emailAddress,
                                               -1)) >= 0) {
            tmpne = X509_NAME_get_entry(dn_subject, i);
            X509_NAME_delete_entry(dn_subject, i);
            X509_NAME_ENTRY_free(tmpne);
        }
    }
    if (BN_is_zero(serial))
        row[DB_serial] = BUF_strdup("00");
    else
        row[DB_serial] = BN_bn2hex(serial);
    if (row[DB_serial] == NULL) {
        BIO_printf(bio_err, "Memory allocation failure\n");
        goto end;
    }
    if (db->attributes.unique_subject) {
        OPENSSL_STRING *crow = row;
        rrow = TXT_DB_get_by_index(db->db, DB_name, crow);
        if (rrow != NULL) {
            BIO_printf(bio_err,
                       "ERROR:There is already a certificate for %s\n",
                       row[DB_name]);
        }
    }
    if (rrow == NULL) {
        rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
        if (rrow != NULL) {
            BIO_printf(bio_err,
                       "ERROR:Serial number %s has already been issued,\n",
                       row[DB_serial]);
            BIO_printf(bio_err,
                       "      check the database/serial_file for corruption\n");
        }
    }
    if (rrow != NULL) {
        BIO_printf(bio_err, "The matching entry has the following details\n");
        if (rrow[DB_type][0] == 'E')
            p = "Expired";
        else if (rrow[DB_type][0] == 'R')
            p = "Revoked";
        else if (rrow[DB_type][0] == 'V')
            p = "Valid";
        else
            p = "\ninvalid type, Data base error\n";
        BIO_printf(bio_err, "Type          :%s\n", p);;
        if (rrow[DB_type][0] == 'R') {
            p = rrow[DB_exp_date];
            if (p == NULL)
                p = "undef";
            BIO_printf(bio_err, "Was revoked on:%s\n", p);
        }
        p = rrow[DB_exp_date];
        if (p == NULL)
            p = "undef";
        BIO_printf(bio_err, "Expires on    :%s\n", p);
        p = rrow[DB_serial];
        if (p == NULL)
            p = "undef";
        BIO_printf(bio_err, "Serial Number :%s\n", p);
        p = rrow[DB_file];
        if (p == NULL)
            p = "undef";
        BIO_printf(bio_err, "File name     :%s\n", p);
        p = rrow[DB_name];
        if (p == NULL)
            p = "undef";
        BIO_printf(bio_err, "Subject Name  :%s\n", p);
        ok = -1;
        goto end;
    }
    if (verbose)
        BIO_printf(bio_err,
                   "Everything appears to be ok, creating and signing the certificate\n");
    if ((ret = X509_new()) == NULL)
        goto end;
#ifdef X509_V3
    if (!X509_set_version(ret, 2))
        goto end;
#endif
    if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)
        goto end;
    if (selfsign) {
        if (!X509_set_issuer_name(ret, subject))
            goto end;
    } else {
        if (!X509_set_issuer_name(ret, X509_get_subject_name(x509)))
            goto end;
    }
    if (strcmp(startdate, "today") == 0)
        X509_gmtime_adj(X509_get_notBefore(ret), 0);
    else
        ASN1_TIME_set_string(X509_get_notBefore(ret), startdate);
    if (enddate == NULL)
        X509_time_adj_ex(X509_get_notAfter(ret), days, 0, NULL);
    else {
        int tdays;
        ASN1_TIME_set_string(X509_get_notAfter(ret), enddate);
        ASN1_TIME_diff(&tdays, NULL, NULL, X509_get_notAfter(ret));
        days = tdays;
    }
    if (!X509_set_subject_name(ret, subject))
        goto end;
    pktmp = X509_REQ_get_pubkey(req);
    i = X509_set_pubkey(ret, pktmp);
    EVP_PKEY_free(pktmp);
    if (!i)
        goto end;
    if (ext_sect) {
        X509V3_CTX ctx;
        X509_set_version(ret, 2);
        if (selfsign)
            X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
        else
            X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
        if (extconf) {
            if (verbose)
                BIO_printf(bio_err, "Extra configuration file found\n");
            X509V3_set_nconf(&ctx, extconf);
            if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect, ret)) {
                BIO_printf(bio_err,
                           "ERROR: adding extensions in section %s\n",
                           ext_sect);
                ERR_print_errors(bio_err);
                goto end;
            }
            if (verbose)
                BIO_printf(bio_err,
                           "Successfully added extensions from file.\n");
        } else if (ext_sect) {
            X509V3_set_nconf(&ctx, lconf);
            if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) {
                BIO_printf(bio_err,
                           "ERROR: adding extensions in section %s\n",
                           ext_sect);
                ERR_print_errors(bio_err);
                goto end;
            }
            if (verbose)
                BIO_printf(bio_err,
                           "Successfully added extensions from config\n");
        }
    }
    if (!copy_extensions(ret, req, ext_copy)) {
        BIO_printf(bio_err, "ERROR: adding extensions from request\n");
        ERR_print_errors(bio_err);
        goto end;
    }
    if (email_dn == 0) {
        if (!X509_set_subject_name(ret, dn_subject))
            goto end;
    }
    if (!default_op) {
        BIO_printf(bio_err, "Certificate Details:\n");
        certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
        X509_print_ex(bio_err, ret, nameopt, certopt);
    }
    BIO_printf(bio_err, "Certificate is to be certified until ");
    ASN1_TIME_print(bio_err, X509_get_notAfter(ret));
    if (days)
        BIO_printf(bio_err, " (%ld days)", days);
    BIO_printf(bio_err, "\n");
    if (!batch) {
        BIO_printf(bio_err, "Sign the certificate? [y/n]:");
        (void)BIO_flush(bio_err);
        buf[0] = '\0';
        if (!fgets(buf, sizeof(buf) - 1, stdin)) {
            BIO_printf(bio_err,
                       "CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
            ok = 0;
            goto end;
        }
        if (!((buf[0] == 'y') || (buf[0] == 'Y'))) {
            BIO_printf(bio_err, "CERTIFICATE WILL NOT BE CERTIFIED\n");
            ok = 0;
            goto end;
        }
    }
    pktmp = X509_get_pubkey(ret);
    if (EVP_PKEY_missing_parameters(pktmp) &&
        !EVP_PKEY_missing_parameters(pkey))
        EVP_PKEY_copy_parameters(pktmp, pkey);
    EVP_PKEY_free(pktmp);
    if (!do_X509_sign(ret, pkey, dgst, sigopts))
        goto end;
    row[DB_type] = app_malloc(2, "row db type");
    tm = X509_get_notAfter(ret);
    row[DB_exp_date] = app_malloc(tm->length + 1, "row expdate");
    memcpy(row[DB_exp_date], tm->data, tm->length);
    row[DB_exp_date][tm->length] = '\0';
    row[DB_rev_date] = NULL;
    row[DB_file] = app_malloc(8, "row file");
    row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
    if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
        (row[DB_file] == NULL) || (row[DB_name] == NULL)) {
        BIO_printf(bio_err, "Memory allocation failure\n");
        goto end;
    }
    BUF_strlcpy(row[DB_file], "unknown", 8);
    row[DB_type][0] = 'V';
    row[DB_type][1] = '\0';
    irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row space");
    for (i = 0; i < DB_NUMBER; i++) {
        irow[i] = row[i];
        row[i] = NULL;
    }
    irow[DB_NUMBER] = NULL;
    if (!TXT_DB_insert(db->db, irow)) {
        BIO_printf(bio_err, "failed to update database\n");
        BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
        goto end;
    }
    ok = 1;
 end:
    for (i = 0; i < DB_NUMBER; i++)
        OPENSSL_free(row[i]);
    X509_NAME_free(CAname);
    X509_NAME_free(subject);
    if (dn_subject != subject)
        X509_NAME_free(dn_subject);
    ASN1_UTCTIME_free(tmptm);
    if (ok <= 0)
        X509_free(ret);
    else
        *xret = ret;
    return (ok);
}
['static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,\n                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,\n                   STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,\n                   char *subj, unsigned long chtype, int multirdn,\n                   int email_dn, char *startdate, char *enddate, long days,\n                   int batch, int verbose, X509_REQ *req, char *ext_sect,\n                   CONF *lconf, unsigned long certopt, unsigned long nameopt,\n                   int default_op, int ext_copy, int selfsign)\n{\n    X509_NAME *name = NULL, *CAname = NULL, *subject = NULL, *dn_subject =\n        NULL;\n    ASN1_UTCTIME *tm, *tmptm;\n    ASN1_STRING *str, *str2;\n    ASN1_OBJECT *obj;\n    X509 *ret = NULL;\n    X509_NAME_ENTRY *ne;\n    X509_NAME_ENTRY *tne, *push;\n    EVP_PKEY *pktmp;\n    int ok = -1, i, j, last, nid;\n    const char *p;\n    CONF_VALUE *cv;\n    OPENSSL_STRING row[DB_NUMBER];\n    OPENSSL_STRING *irow = NULL;\n    OPENSSL_STRING *rrow = NULL;\n    char buf[25];\n    tmptm = ASN1_UTCTIME_new();\n    if (tmptm == NULL) {\n        BIO_printf(bio_err, "malloc error\\n");\n        return (0);\n    }\n    for (i = 0; i < DB_NUMBER; i++)\n        row[i] = NULL;\n    if (subj) {\n        X509_NAME *n = parse_name(subj, chtype, multirdn);\n        if (!n) {\n            ERR_print_errors(bio_err);\n            goto end;\n        }\n        X509_REQ_set_subject_name(req, n);\n        X509_NAME_free(n);\n    }\n    if (default_op)\n        BIO_printf(bio_err,\n                   "The Subject\'s Distinguished Name is as follows\\n");\n    name = X509_REQ_get_subject_name(req);\n    for (i = 0; i < X509_NAME_entry_count(name); i++) {\n        ne = X509_NAME_get_entry(name, i);\n        str = X509_NAME_ENTRY_get_data(ne);\n        obj = X509_NAME_ENTRY_get_object(ne);\n        if (msie_hack) {\n            nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));\n            if (str->type == V_ASN1_UNIVERSALSTRING)\n                ASN1_UNIVERSALSTRING_to_string(str);\n            if ((str->type == V_ASN1_IA5STRING) &&\n                (nid != NID_pkcs9_emailAddress))\n                str->type = V_ASN1_T61STRING;\n            if ((nid == NID_pkcs9_emailAddress) &&\n                (str->type == V_ASN1_PRINTABLESTRING))\n                str->type = V_ASN1_IA5STRING;\n        }\n        if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))\n            continue;\n        if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&\n            (str->type != V_ASN1_IA5STRING)) {\n            BIO_printf(bio_err,\n                       "\\nemailAddress type needs to be of type IA5STRING\\n");\n            goto end;\n        }\n        if ((str->type != V_ASN1_BMPSTRING)\n            && (str->type != V_ASN1_UTF8STRING)) {\n            j = ASN1_PRINTABLE_type(str->data, str->length);\n            if (((j == V_ASN1_T61STRING) &&\n                 (str->type != V_ASN1_T61STRING)) ||\n                ((j == V_ASN1_IA5STRING) &&\n                 (str->type == V_ASN1_PRINTABLESTRING))) {\n                BIO_printf(bio_err,\n                           "\\nThe string contains characters that are illegal for the ASN.1 type\\n");\n                goto end;\n            }\n        }\n        if (default_op)\n            old_entry_print(obj, str);\n    }\n    if ((subject = X509_NAME_new()) == NULL) {\n        BIO_printf(bio_err, "Memory allocation failure\\n");\n        goto end;\n    }\n    if (selfsign)\n        CAname = X509_NAME_dup(name);\n    else\n        CAname = X509_NAME_dup(X509_get_subject_name(x509));\n    if (CAname == NULL)\n        goto end;\n    str = str2 = NULL;\n    for (i = 0; i < sk_CONF_VALUE_num(policy); i++) {\n        cv = sk_CONF_VALUE_value(policy, i);\n        if ((j = OBJ_txt2nid(cv->name)) == NID_undef) {\n            BIO_printf(bio_err,\n                       "%s:unknown object type in \'policy\' configuration\\n",\n                       cv->name);\n            goto end;\n        }\n        obj = OBJ_nid2obj(j);\n        last = -1;\n        for (;;) {\n            j = X509_NAME_get_index_by_OBJ(name, obj, last);\n            if (j < 0) {\n                if (last != -1)\n                    break;\n                tne = NULL;\n            } else {\n                tne = X509_NAME_get_entry(name, j);\n            }\n            last = j;\n            push = NULL;\n            if (strcmp(cv->value, "optional") == 0) {\n                if (tne != NULL)\n                    push = tne;\n            } else if (strcmp(cv->value, "supplied") == 0) {\n                if (tne == NULL) {\n                    BIO_printf(bio_err,\n                               "The %s field needed to be supplied and was missing\\n",\n                               cv->name);\n                    goto end;\n                } else\n                    push = tne;\n            } else if (strcmp(cv->value, "match") == 0) {\n                int last2;\n                if (tne == NULL) {\n                    BIO_printf(bio_err,\n                               "The mandatory %s field was missing\\n",\n                               cv->name);\n                    goto end;\n                }\n                last2 = -1;\n again2:\n                j = X509_NAME_get_index_by_OBJ(CAname, obj, last2);\n                if ((j < 0) && (last2 == -1)) {\n                    BIO_printf(bio_err,\n                               "The %s field does not exist in the CA certificate,\\nthe \'policy\' is misconfigured\\n",\n                               cv->name);\n                    goto end;\n                }\n                if (j >= 0) {\n                    push = X509_NAME_get_entry(CAname, j);\n                    str = X509_NAME_ENTRY_get_data(tne);\n                    str2 = X509_NAME_ENTRY_get_data(push);\n                    last2 = j;\n                    if (ASN1_STRING_cmp(str, str2) != 0)\n                        goto again2;\n                }\n                if (j < 0) {\n                    BIO_printf(bio_err,\n                               "The %s field needed to be the same in the\\nCA certificate (%s) and the request (%s)\\n",\n                               cv->name,\n                               ((str2 == NULL) ? "NULL" : (char *)str2->data),\n                               ((str == NULL) ? "NULL" : (char *)str->data));\n                    goto end;\n                }\n            } else {\n                BIO_printf(bio_err,\n                           "%s:invalid type in \'policy\' configuration\\n",\n                           cv->value);\n                goto end;\n            }\n            if (push != NULL) {\n                if (!X509_NAME_add_entry(subject, push, -1, 0)) {\n                    X509_NAME_ENTRY_free(push);\n                    BIO_printf(bio_err, "Memory allocation failure\\n");\n                    goto end;\n                }\n            }\n            if (j < 0)\n                break;\n        }\n    }\n    if (preserve) {\n        X509_NAME_free(subject);\n        subject = X509_NAME_dup(name);\n        if (subject == NULL)\n            goto end;\n    }\n    if (verbose)\n        BIO_printf(bio_err,\n                   "The subject name appears to be ok, checking data base for clashes\\n");\n    if (email_dn)\n        dn_subject = subject;\n    else {\n        X509_NAME_ENTRY *tmpne;\n        if ((dn_subject = X509_NAME_dup(subject)) == NULL) {\n            BIO_printf(bio_err, "Memory allocation failure\\n");\n            goto end;\n        }\n        while ((i = X509_NAME_get_index_by_NID(dn_subject,\n                                               NID_pkcs9_emailAddress,\n                                               -1)) >= 0) {\n            tmpne = X509_NAME_get_entry(dn_subject, i);\n            X509_NAME_delete_entry(dn_subject, i);\n            X509_NAME_ENTRY_free(tmpne);\n        }\n    }\n    if (BN_is_zero(serial))\n        row[DB_serial] = BUF_strdup("00");\n    else\n        row[DB_serial] = BN_bn2hex(serial);\n    if (row[DB_serial] == NULL) {\n        BIO_printf(bio_err, "Memory allocation failure\\n");\n        goto end;\n    }\n    if (db->attributes.unique_subject) {\n        OPENSSL_STRING *crow = row;\n        rrow = TXT_DB_get_by_index(db->db, DB_name, crow);\n        if (rrow != NULL) {\n            BIO_printf(bio_err,\n                       "ERROR:There is already a certificate for %s\\n",\n                       row[DB_name]);\n        }\n    }\n    if (rrow == NULL) {\n        rrow = TXT_DB_get_by_index(db->db, DB_serial, row);\n        if (rrow != NULL) {\n            BIO_printf(bio_err,\n                       "ERROR:Serial number %s has already been issued,\\n",\n                       row[DB_serial]);\n            BIO_printf(bio_err,\n                       "      check the database/serial_file for corruption\\n");\n        }\n    }\n    if (rrow != NULL) {\n        BIO_printf(bio_err, "The matching entry has the following details\\n");\n        if (rrow[DB_type][0] == \'E\')\n            p = "Expired";\n        else if (rrow[DB_type][0] == \'R\')\n            p = "Revoked";\n        else if (rrow[DB_type][0] == \'V\')\n            p = "Valid";\n        else\n            p = "\\ninvalid type, Data base error\\n";\n        BIO_printf(bio_err, "Type          :%s\\n", p);;\n        if (rrow[DB_type][0] == \'R\') {\n            p = rrow[DB_exp_date];\n            if (p == NULL)\n                p = "undef";\n            BIO_printf(bio_err, "Was revoked on:%s\\n", p);\n        }\n        p = rrow[DB_exp_date];\n        if (p == NULL)\n            p = "undef";\n        BIO_printf(bio_err, "Expires on    :%s\\n", p);\n        p = rrow[DB_serial];\n        if (p == NULL)\n            p = "undef";\n        BIO_printf(bio_err, "Serial Number :%s\\n", p);\n        p = rrow[DB_file];\n        if (p == NULL)\n            p = "undef";\n        BIO_printf(bio_err, "File name     :%s\\n", p);\n        p = rrow[DB_name];\n        if (p == NULL)\n            p = "undef";\n        BIO_printf(bio_err, "Subject Name  :%s\\n", p);\n        ok = -1;\n        goto end;\n    }\n    if (verbose)\n        BIO_printf(bio_err,\n                   "Everything appears to be ok, creating and signing the certificate\\n");\n    if ((ret = X509_new()) == NULL)\n        goto end;\n#ifdef X509_V3\n    if (!X509_set_version(ret, 2))\n        goto end;\n#endif\n    if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)\n        goto end;\n    if (selfsign) {\n        if (!X509_set_issuer_name(ret, subject))\n            goto end;\n    } else {\n        if (!X509_set_issuer_name(ret, X509_get_subject_name(x509)))\n            goto end;\n    }\n    if (strcmp(startdate, "today") == 0)\n        X509_gmtime_adj(X509_get_notBefore(ret), 0);\n    else\n        ASN1_TIME_set_string(X509_get_notBefore(ret), startdate);\n    if (enddate == NULL)\n        X509_time_adj_ex(X509_get_notAfter(ret), days, 0, NULL);\n    else {\n        int tdays;\n        ASN1_TIME_set_string(X509_get_notAfter(ret), enddate);\n        ASN1_TIME_diff(&tdays, NULL, NULL, X509_get_notAfter(ret));\n        days = tdays;\n    }\n    if (!X509_set_subject_name(ret, subject))\n        goto end;\n    pktmp = X509_REQ_get_pubkey(req);\n    i = X509_set_pubkey(ret, pktmp);\n    EVP_PKEY_free(pktmp);\n    if (!i)\n        goto end;\n    if (ext_sect) {\n        X509V3_CTX ctx;\n        X509_set_version(ret, 2);\n        if (selfsign)\n            X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);\n        else\n            X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);\n        if (extconf) {\n            if (verbose)\n                BIO_printf(bio_err, "Extra configuration file found\\n");\n            X509V3_set_nconf(&ctx, extconf);\n            if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect, ret)) {\n                BIO_printf(bio_err,\n                           "ERROR: adding extensions in section %s\\n",\n                           ext_sect);\n                ERR_print_errors(bio_err);\n                goto end;\n            }\n            if (verbose)\n                BIO_printf(bio_err,\n                           "Successfully added extensions from file.\\n");\n        } else if (ext_sect) {\n            X509V3_set_nconf(&ctx, lconf);\n            if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) {\n                BIO_printf(bio_err,\n                           "ERROR: adding extensions in section %s\\n",\n                           ext_sect);\n                ERR_print_errors(bio_err);\n                goto end;\n            }\n            if (verbose)\n                BIO_printf(bio_err,\n                           "Successfully added extensions from config\\n");\n        }\n    }\n    if (!copy_extensions(ret, req, ext_copy)) {\n        BIO_printf(bio_err, "ERROR: adding extensions from request\\n");\n        ERR_print_errors(bio_err);\n        goto end;\n    }\n    if (email_dn == 0) {\n        if (!X509_set_subject_name(ret, dn_subject))\n            goto end;\n    }\n    if (!default_op) {\n        BIO_printf(bio_err, "Certificate Details:\\n");\n        certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;\n        X509_print_ex(bio_err, ret, nameopt, certopt);\n    }\n    BIO_printf(bio_err, "Certificate is to be certified until ");\n    ASN1_TIME_print(bio_err, X509_get_notAfter(ret));\n    if (days)\n        BIO_printf(bio_err, " (%ld days)", days);\n    BIO_printf(bio_err, "\\n");\n    if (!batch) {\n        BIO_printf(bio_err, "Sign the certificate? [y/n]:");\n        (void)BIO_flush(bio_err);\n        buf[0] = \'\\0\';\n        if (!fgets(buf, sizeof(buf) - 1, stdin)) {\n            BIO_printf(bio_err,\n                       "CERTIFICATE WILL NOT BE CERTIFIED: I/O error\\n");\n            ok = 0;\n            goto end;\n        }\n        if (!((buf[0] == \'y\') || (buf[0] == \'Y\'))) {\n            BIO_printf(bio_err, "CERTIFICATE WILL NOT BE CERTIFIED\\n");\n            ok = 0;\n            goto end;\n        }\n    }\n    pktmp = X509_get_pubkey(ret);\n    if (EVP_PKEY_missing_parameters(pktmp) &&\n        !EVP_PKEY_missing_parameters(pkey))\n        EVP_PKEY_copy_parameters(pktmp, pkey);\n    EVP_PKEY_free(pktmp);\n    if (!do_X509_sign(ret, pkey, dgst, sigopts))\n        goto end;\n    row[DB_type] = app_malloc(2, "row db type");\n    tm = X509_get_notAfter(ret);\n    row[DB_exp_date] = app_malloc(tm->length + 1, "row expdate");\n    memcpy(row[DB_exp_date], tm->data, tm->length);\n    row[DB_exp_date][tm->length] = \'\\0\';\n    row[DB_rev_date] = NULL;\n    row[DB_file] = app_malloc(8, "row file");\n    row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);\n    if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||\n        (row[DB_file] == NULL) || (row[DB_name] == NULL)) {\n        BIO_printf(bio_err, "Memory allocation failure\\n");\n        goto end;\n    }\n    BUF_strlcpy(row[DB_file], "unknown", 8);\n    row[DB_type][0] = \'V\';\n    row[DB_type][1] = \'\\0\';\n    irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row space");\n    for (i = 0; i < DB_NUMBER; i++) {\n        irow[i] = row[i];\n        row[i] = NULL;\n    }\n    irow[DB_NUMBER] = NULL;\n    if (!TXT_DB_insert(db->db, irow)) {\n        BIO_printf(bio_err, "failed to update database\\n");\n        BIO_printf(bio_err, "TXT_DB error number %ld\\n", db->db->error);\n        goto end;\n    }\n    ok = 1;\n end:\n    for (i = 0; i < DB_NUMBER; i++)\n        OPENSSL_free(row[i]);\n    X509_NAME_free(CAname);\n    X509_NAME_free(subject);\n    if (dn_subject != subject)\n        X509_NAME_free(dn_subject);\n    ASN1_UTCTIME_free(tmptm);\n    if (ok <= 0)\n        X509_free(ret);\n    else\n        *xret = ret;\n    return (ok);\n}', 'IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTCTIME)', 'X509_NAME *X509_REQ_get_subject_name(X509_REQ *req)\n{\n    return req->req_info.subject;\n}', 'int X509_NAME_entry_count(X509_NAME *name)\n{\n    if (name == NULL)\n        return (0);\n    return (sk_X509_NAME_ENTRY_num(name->entries));\n}', 'int sk_num(const _STACK *st)\n{\n    if (st == NULL)\n        return -1;\n    return st->num;\n}', 'X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)\n{\n    if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc\n        || loc < 0)\n        return (NULL);\n    else\n        return (sk_X509_NAME_ENTRY_value(name->entries, loc));\n}', 'void *sk_value(const _STACK *st, int i)\n{\n    if (!st || (i < 0) || (i >= st->num))\n        return NULL;\n    return st->data[i];\n}', 'ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)\n{\n    if (ne == NULL)\n        return (NULL);\n    return (ne->value);\n}', 'ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)\n{\n    if (ne == NULL)\n        return (NULL);\n    return (ne->object);\n}', 'int OBJ_obj2nid(const ASN1_OBJECT *a)\n{\n    const unsigned int *op;\n    ADDED_OBJ ad, *adp;\n    if (a == NULL)\n        return (NID_undef);\n    if (a->nid != 0)\n        return (a->nid);\n    if (a->length == 0)\n        return NID_undef;\n    if (added != NULL) {\n        ad.type = ADDED_DATA;\n        ad.obj = (ASN1_OBJECT *)a;\n        adp = lh_ADDED_OBJ_retrieve(added, &ad);\n        if (adp != NULL)\n            return (adp->obj->nid);\n    }\n    op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);\n    if (op == NULL)\n        return (NID_undef);\n    return (nid_objs[*op].nid);\n}']