~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/certhigh/certhtml.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * The contents of this file are subject to the Mozilla Public
 
3
 * License Version 1.1 (the "License"); you may not use this file
 
4
 * except in compliance with the License. You may obtain a copy of
 
5
 * the License at http://www.mozilla.org/MPL/
 
6
 * 
 
7
 * Software distributed under the License is distributed on an "AS
 
8
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
9
 * implied. See the License for the specific language governing
 
10
 * rights and limitations under the License.
 
11
 * 
 
12
 * The Original Code is the Netscape security libraries.
 
13
 * 
 
14
 * The Initial Developer of the Original Code is Netscape
 
15
 * Communications Corporation.  Portions created by Netscape are 
 
16
 * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
 
17
 * Rights Reserved.
 
18
 * 
 
19
 * Contributor(s):
 
20
 * 
 
21
 * Alternatively, the contents of this file may be used under the
 
22
 * terms of the GNU General Public License Version 2 or later (the
 
23
 * "GPL"), in which case the provisions of the GPL are applicable 
 
24
 * instead of those above.  If you wish to allow use of your 
 
25
 * version of this file only under the terms of the GPL and not to
 
26
 * allow others to use your version of this file under the MPL,
 
27
 * indicate your decision by deleting the provisions above and
 
28
 * replace them with the notice and other provisions required by
 
29
 * the GPL.  If you do not delete the provisions above, a recipient
 
30
 * may use your version of this file under either the MPL or the
 
31
 * GPL.
 
32
 */
 
33
 
 
34
/*
 
35
 * certhtml.c --- convert a cert to html
 
36
 *
 
37
 * $Id: certhtml.c,v 1.4 2003/09/19 04:08:49 jpierre%netscape.com Exp $
 
38
 */
 
39
 
 
40
#include "seccomon.h"
 
41
#include "secitem.h"
 
42
#include "sechash.h"
 
43
#include "cert.h"
 
44
#include "keyhi.h"
 
45
#include "secder.h"
 
46
#include "prprf.h"
 
47
#include "secport.h"
 
48
#include "secasn1.h"
 
49
#include "pk11func.h"
 
50
 
 
51
static char *hex = "0123456789ABCDEF";
 
52
 
 
53
/*
 
54
** Convert a der-encoded integer to a hex printable string form
 
55
*/
 
56
char *CERT_Hexify (SECItem *i, int do_colon)
 
57
{
 
58
    unsigned char *cp, *end;
 
59
    char *rv, *o;
 
60
 
 
61
    if (!i->len) {
 
62
        return PORT_Strdup("00");
 
63
    }
 
64
 
 
65
    rv = o = (char*) PORT_Alloc(i->len * 3);
 
66
    if (!rv) return rv;
 
67
 
 
68
    cp = i->data;
 
69
    end = cp + i->len;
 
70
    while (cp < end) {
 
71
        unsigned char ch = *cp++;
 
72
        *o++ = hex[(ch >> 4) & 0xf];
 
73
        *o++ = hex[ch & 0xf];
 
74
        if (cp != end) {
 
75
            if (do_colon) {
 
76
                *o++ = ':';
 
77
            }
 
78
        } 
 
79
    }
 
80
    *o = 0;           /* Null terminate the string */
 
81
    return rv;
 
82
}
 
83
 
 
84
static char *
 
85
gatherStrings(char **strings)
 
86
{
 
87
    char **strs;
 
88
    int len;
 
89
    char *ret;
 
90
    char *s;
 
91
 
 
92
    /* find total length of all strings */
 
93
    strs = strings;
 
94
    len = 0;
 
95
    while ( *strs ) {
 
96
        len += PORT_Strlen(*strs);
 
97
        strs++;
 
98
    }
 
99
    
 
100
    /* alloc enough memory for it */
 
101
    ret = (char*)PORT_Alloc(len + 1);
 
102
    if ( !ret ) {
 
103
        return(ret);
 
104
    }
 
105
 
 
106
    s = ret;
 
107
    
 
108
    /* copy the strings */
 
109
    strs = strings;
 
110
    while ( *strs ) {
 
111
        PORT_Strcpy(s, *strs);
 
112
        s += PORT_Strlen(*strs);
 
113
        strs++;
 
114
    }
 
115
 
 
116
    return( ret );
 
117
}
 
118
 
 
119
#define BREAK "<br>"
 
120
#define BREAKLEN 4
 
121
#define COMMA ", "
 
122
#define COMMALEN 2
 
123
 
 
124
#define MAX_OUS 20
 
125
#define MAX_DC MAX_OUS
 
126
 
 
127
 
 
128
char *CERT_FormatName (CERTName *name)
 
129
{
 
130
    CERTRDN** rdns;
 
131
    CERTRDN * rdn;
 
132
    CERTAVA** avas;
 
133
    CERTAVA*  ava;
 
134
    char *    buf       = 0;
 
135
    char *    tmpbuf    = 0;
 
136
    SECItem * cn        = 0;
 
137
    SECItem * email     = 0;
 
138
    SECItem * org       = 0;
 
139
    SECItem * loc       = 0;
 
140
    SECItem * state     = 0;
 
141
    SECItem * country   = 0;
 
142
    SECItem * dq        = 0;
 
143
 
 
144
    unsigned  len       = 0;
 
145
    int       tag;
 
146
    int       i;
 
147
    int       ou_count = 0;
 
148
    int       dc_count = 0;
 
149
    PRBool    first;
 
150
    SECItem * orgunit[MAX_OUS];
 
151
    SECItem * dc[MAX_DC];
 
152
 
 
153
    /* Loop over name components and gather the interesting ones */
 
154
    rdns = name->rdns;
 
155
    while ((rdn = *rdns++) != 0) {
 
156
        avas = rdn->avas;
 
157
        while ((ava = *avas++) != 0) {
 
158
            tag = CERT_GetAVATag(ava);
 
159
            switch(tag) {
 
160
              case SEC_OID_AVA_COMMON_NAME:
 
161
                cn = CERT_DecodeAVAValue(&ava->value);
 
162
                len += cn->len;
 
163
                break;
 
164
              case SEC_OID_AVA_COUNTRY_NAME:
 
165
                country = CERT_DecodeAVAValue(&ava->value);
 
166
                len += country->len;
 
167
                break;
 
168
              case SEC_OID_AVA_LOCALITY:
 
169
                loc = CERT_DecodeAVAValue(&ava->value);
 
170
                len += loc->len;
 
171
                break;
 
172
              case SEC_OID_AVA_STATE_OR_PROVINCE:
 
173
                state = CERT_DecodeAVAValue(&ava->value);
 
174
                len += state->len;
 
175
                break;
 
176
              case SEC_OID_AVA_ORGANIZATION_NAME:
 
177
                org = CERT_DecodeAVAValue(&ava->value);
 
178
                len += org->len;
 
179
                break;
 
180
              case SEC_OID_AVA_DN_QUALIFIER:
 
181
                dq = CERT_DecodeAVAValue(&ava->value);
 
182
                len += dq->len;
 
183
                break;
 
184
              case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
 
185
                if (ou_count < MAX_OUS) {
 
186
                        orgunit[ou_count] = CERT_DecodeAVAValue(&ava->value);
 
187
                        len += orgunit[ou_count++]->len;
 
188
                }
 
189
                break;
 
190
              case SEC_OID_AVA_DC:
 
191
                if (dc_count < MAX_DC) {
 
192
                        dc[dc_count] = CERT_DecodeAVAValue(&ava->value);
 
193
                        len += dc[dc_count++]->len;
 
194
                }
 
195
                break;
 
196
              case SEC_OID_PKCS9_EMAIL_ADDRESS:
 
197
              case SEC_OID_RFC1274_MAIL:
 
198
                email = CERT_DecodeAVAValue(&ava->value);
 
199
                len += email->len;
 
200
                break;
 
201
              default:
 
202
                break;
 
203
            }
 
204
        }
 
205
    }
 
206
 
 
207
    /* XXX - add some for formatting */
 
208
    len += 128;
 
209
 
 
210
    /* allocate buffer */
 
211
    buf = (char *)PORT_Alloc(len);
 
212
    if ( !buf ) {
 
213
        return(0);
 
214
    }
 
215
 
 
216
    tmpbuf = buf;
 
217
    
 
218
    if ( cn ) {
 
219
        PORT_Memcpy(tmpbuf, cn->data, cn->len);
 
220
        tmpbuf += cn->len;
 
221
        PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
 
222
        tmpbuf += BREAKLEN;
 
223
        SECITEM_FreeItem(cn, PR_TRUE);
 
224
    }
 
225
    if ( email ) {
 
226
        PORT_Memcpy(tmpbuf, email->data, email->len);
 
227
        tmpbuf += ( email->len );
 
228
        PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
 
229
        tmpbuf += BREAKLEN;
 
230
        SECITEM_FreeItem(email, PR_TRUE);
 
231
    }
 
232
    for (i=ou_count-1; i >= 0; i--) {
 
233
        PORT_Memcpy(tmpbuf, orgunit[i]->data, orgunit[i]->len);
 
234
        tmpbuf += ( orgunit[i]->len );
 
235
        PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
 
236
        tmpbuf += BREAKLEN;
 
237
        SECITEM_FreeItem(orgunit[i], PR_TRUE);
 
238
    }
 
239
    if ( dq ) {
 
240
        PORT_Memcpy(tmpbuf, dq->data, dq->len);
 
241
        tmpbuf += ( dq->len );
 
242
        PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
 
243
        tmpbuf += BREAKLEN;
 
244
        SECITEM_FreeItem(dq, PR_TRUE);
 
245
    }
 
246
    if ( org ) {
 
247
        PORT_Memcpy(tmpbuf, org->data, org->len);
 
248
        tmpbuf += ( org->len );
 
249
        PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
 
250
        tmpbuf += BREAKLEN;
 
251
        SECITEM_FreeItem(org, PR_TRUE);
 
252
    }
 
253
    for (i=dc_count-1; i >= 0; i--) {
 
254
        PORT_Memcpy(tmpbuf, dc[i]->data, dc[i]->len);
 
255
        tmpbuf += ( dc[i]->len );
 
256
        PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
 
257
        tmpbuf += BREAKLEN;
 
258
        SECITEM_FreeItem(dc[i], PR_TRUE);
 
259
    }
 
260
    first = PR_TRUE;
 
261
    if ( loc ) {
 
262
        PORT_Memcpy(tmpbuf, loc->data,  loc->len);
 
263
        tmpbuf += ( loc->len );
 
264
        first = PR_FALSE;
 
265
        SECITEM_FreeItem(loc, PR_TRUE);
 
266
    }
 
267
    if ( state ) {
 
268
        if ( !first ) {
 
269
            PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
 
270
            tmpbuf += COMMALEN;
 
271
        }
 
272
        PORT_Memcpy(tmpbuf, state->data, state->len);
 
273
        tmpbuf += ( state->len );
 
274
        first = PR_FALSE;
 
275
        SECITEM_FreeItem(state, PR_TRUE);
 
276
    }
 
277
    if ( country ) {
 
278
        if ( !first ) {
 
279
            PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
 
280
            tmpbuf += COMMALEN;
 
281
        }
 
282
        PORT_Memcpy(tmpbuf, country->data, country->len);
 
283
        tmpbuf += ( country->len );
 
284
        first = PR_FALSE;
 
285
        SECITEM_FreeItem(country, PR_TRUE);
 
286
    }
 
287
    if ( !first ) {
 
288
        PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
 
289
        tmpbuf += BREAKLEN;
 
290
    }
 
291
 
 
292
    *tmpbuf = 0;
 
293
 
 
294
    return(buf);
 
295
}
 
296
 
 
297
static char *sec_FortezzaClearance(SECItem *clearance) {
 
298
    unsigned char clr = 0;
 
299
 
 
300
    if (clearance->len > 0) { clr = clearance->data[0]; }
 
301
 
 
302
    if (clr & 0x4) return "Top Secret";
 
303
    if (clr & 0x8) return "Secret";
 
304
    if (clr & 0x10) return "Confidential";
 
305
    if (clr & 0x20) return "Sensitive";
 
306
    if (clr & 0x40) return "Unclassified";
 
307
    return "None";
 
308
}
 
309
 
 
310
static char *sec_FortezzaMessagePrivilege(SECItem *priv) {
 
311
    unsigned char clr = 0;
 
312
 
 
313
    if (priv->len > 0) { clr = (priv->data[0]) & 0x78; }
 
314
 
 
315
    if (clr == 0x00) {
 
316
        return "None";
 
317
    } else {
 
318
 
 
319
        return PR_smprintf("%s%s%s%s%s%s%s",
 
320
 
 
321
            clr&0x40?"Critical/Flash":"",
 
322
            (clr&0x40) && (clr&0x38) ? ", " : "" ,
 
323
 
 
324
            clr&0x20?"Immediate/Priority":"",
 
325
            (clr&0x20) && (clr&0x18) ? ", " : "" ,
 
326
 
 
327
            clr&0x10?"Routine/Deferred":"",
 
328
            (clr&0x10) && (clr&0x08) ? ", " : "" ,
 
329
 
 
330
            clr&0x08?"Rekey Agent":"");
 
331
    }
 
332
 
 
333
}
 
334
                                        
 
335
static char *sec_FortezzaCertPrivilege(SECItem *priv) {
 
336
    unsigned char clr = 0;
 
337
 
 
338
    if (priv->len > 0) { clr = priv->data[0]; }
 
339
 
 
340
    return PR_smprintf("%s%s%s%s%s%s%s%s%s%s%s%s",
 
341
        clr&0x40?"Organizational Releaser":"",
 
342
        (clr&0x40) && (clr&0x3e) ? "," : "" ,
 
343
        clr&0x20?"Policy Creation Authority":"",
 
344
        (clr&0x20) && (clr&0x1e) ? "," : "" ,
 
345
        clr&0x10?"Certificate Authority":"",
 
346
        (clr&0x10) && (clr&0x0e) ? "," : "" ,
 
347
        clr&0x08?"Local Managment Authority":"",
 
348
        (clr&0x08) && (clr&0x06) ? "," : "" ,
 
349
        clr&0x04?"Configuration Vector Authority":"",
 
350
        (clr&0x04) && (clr&0x02) ? "," : "" ,
 
351
        clr&0x02?"No Signature Capability":"",
 
352
        clr&0x7e?"":"Signing Only"
 
353
    );
 
354
}
 
355
 
 
356
static char *htmlcertstrings[] = {
 
357
    "<table border=0 cellspacing=0 cellpadding=0><tr><td valign=top>"
 
358
    "<font size=2><b>This Certificate belongs to:</b><br>"
 
359
    "<table border=0 cellspacing=0 cellpadding=0><tr><td>",
 
360
    0, /* image goes here */
 
361
    0,
 
362
    0,
 
363
    "</td><td width=10> </td><td><font size=2>",
 
364
    0, /* subject name goes here */
 
365
    "</td></tr></table></font></td><td width=20> </td><td valign=top>"
 
366
    "<font size=2><b>This Certificate was issued by:</b><br>"
 
367
    "<table border=0 cellspacing=0 cellpadding=0><tr><td>",
 
368
    0, /* image goes here */
 
369
    0,
 
370
    0,
 
371
    "</td><td width=10> </td><td><font size=2>",
 
372
    0, /* issuer name goes here */
 
373
    "</td></tr></table></font></td></tr></table>"
 
374
    "<b>Serial Number:</b> ",
 
375
    0,
 
376
    "<br><b>This Certificate is valid from ",
 
377
    0, /* notBefore goes here */
 
378
    " to ",
 
379
    0, /* notAfter does here */
 
380
    "</b><br><b>Clearance:</b>",
 
381
    0,
 
382
    "<br><b>DSS Privileges:</b>",
 
383
    0,
 
384
    "<br><b>KEA Privileges:</b>",
 
385
    0,
 
386
    "<br><b>KMID:</b>",
 
387
    0,
 
388
    "<br><b>Certificate Fingerprint:</b>"
 
389
    "<table border=0 cellspacing=0 cellpadding=0><tr>"
 
390
    "<td width=10> </td><td><font size=2>",
 
391
    0, /* fingerprint goes here */
 
392
    "</td></tr></table>",
 
393
    0, /* comment header goes here */
 
394
    0, /* comment goes here */
 
395
    0, /* comment trailer goes here */
 
396
    0
 
397
};
 
398
 
 
399
char *
 
400
CERT_HTMLCertInfo(CERTCertificate *cert, PRBool showImages, PRBool showIssuer)
 
401
{
 
402
    SECStatus rv;
 
403
    char *issuer, *subject, *serialNumber, *version;
 
404
    char *notBefore, *notAfter;
 
405
    char *ret;
 
406
    char *nickname;
 
407
    SECItem dummyitem;
 
408
    unsigned char fingerprint[16];   /* result of MD5, always 16 bytes */
 
409
    char *fpstr;
 
410
    SECItem fpitem;
 
411
    char *commentstring = NULL;
 
412
    SECKEYPublicKey *pubk;
 
413
    char *DSSPriv;
 
414
    char *KMID = NULL;
 
415
    char *servername;
 
416
    
 
417
    if (!cert) {
 
418
        return(0);
 
419
    }
 
420
 
 
421
    issuer = CERT_FormatName (&cert->issuer);
 
422
    subject = CERT_FormatName (&cert->subject);
 
423
    version = CERT_Hexify (&cert->version,1);
 
424
    serialNumber = CERT_Hexify (&cert->serialNumber,1);
 
425
    notBefore = DER_TimeChoiceDayToAscii(&cert->validity.notBefore);
 
426
    notAfter = DER_TimeChoiceDayToAscii(&cert->validity.notAfter);
 
427
    servername = CERT_FindNSStringExtension(cert,
 
428
                                   SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME);
 
429
 
 
430
    nickname = cert->nickname;
 
431
    if ( nickname == NULL ) {
 
432
        showImages = PR_FALSE;
 
433
    }
 
434
 
 
435
    dummyitem.data = NULL;
 
436
    rv = CERT_FindCertExtension(cert, SEC_OID_NS_CERT_EXT_SUBJECT_LOGO,
 
437
                               &dummyitem);
 
438
    if ( dummyitem.data ) {
 
439
        PORT_Free(dummyitem.data);
 
440
    }
 
441
    
 
442
    if ( rv || !showImages ) {
 
443
        htmlcertstrings[1] = "";
 
444
        htmlcertstrings[2] = "";
 
445
        htmlcertstrings[3] = "";
 
446
    } else {
 
447
        htmlcertstrings[1] = "<img src=\"about:security?subject-logo=";
 
448
        htmlcertstrings[2] = nickname;
 
449
        htmlcertstrings[3] = "\">";
 
450
    }
 
451
 
 
452
    if ( servername ) {
 
453
        char *tmpstr;
 
454
        tmpstr = (char *)PORT_Alloc(PORT_Strlen(subject) +
 
455
                                    PORT_Strlen(servername) +
 
456
                                    sizeof("<br>") + 1);
 
457
        if ( tmpstr ) {
 
458
            PORT_Strcpy(tmpstr, servername);
 
459
            PORT_Strcat(tmpstr, "<br>");
 
460
            PORT_Strcat(tmpstr, subject);
 
461
            PORT_Free(subject);
 
462
            subject = tmpstr;
 
463
        }
 
464
    }
 
465
    
 
466
    htmlcertstrings[5] = subject;
 
467
 
 
468
    dummyitem.data = NULL;
 
469
    
 
470
    rv = CERT_FindCertExtension(cert, SEC_OID_NS_CERT_EXT_ISSUER_LOGO,
 
471
                               &dummyitem);
 
472
    if ( dummyitem.data ) {
 
473
        PORT_Free(dummyitem.data);
 
474
    }
 
475
    
 
476
    if ( rv || !showImages ) {
 
477
        htmlcertstrings[7] = "";
 
478
        htmlcertstrings[8] = "";
 
479
        htmlcertstrings[9] = "";
 
480
    } else {
 
481
        htmlcertstrings[7] = "<img src=\"about:security?issuer-logo=";
 
482
        htmlcertstrings[8] = nickname;
 
483
        htmlcertstrings[9] = "\">";
 
484
    }
 
485
 
 
486
    
 
487
    if (showIssuer == PR_TRUE) {
 
488
        htmlcertstrings[11] = issuer;
 
489
    } else {
 
490
        htmlcertstrings[11] = "";
 
491
    }
 
492
 
 
493
    htmlcertstrings[13] = serialNumber;
 
494
    htmlcertstrings[15] = notBefore;
 
495
    htmlcertstrings[17] = notAfter;
 
496
 
 
497
    pubk = CERT_ExtractPublicKey(cert);
 
498
    DSSPriv = NULL;
 
499
    if (pubk && (pubk->keyType == fortezzaKey)) {
 
500
        htmlcertstrings[18] = "</b><br><b>Clearance:</b>";
 
501
        htmlcertstrings[19] = sec_FortezzaClearance(
 
502
                                        &pubk->u.fortezza.clearance);
 
503
        htmlcertstrings[20] = "<br><b>DSS Privileges:</b>";
 
504
        DSSPriv = sec_FortezzaCertPrivilege(
 
505
                                        &pubk->u.fortezza.DSSpriviledge);
 
506
        htmlcertstrings[21] = DSSPriv;
 
507
        htmlcertstrings[22] = "<br><b>KEA Privileges:</b>";
 
508
        htmlcertstrings[23] = sec_FortezzaMessagePrivilege(
 
509
                                        &pubk->u.fortezza.KEApriviledge);
 
510
        htmlcertstrings[24] = "<br><b>KMID:</b>";
 
511
        dummyitem.data = &pubk->u.fortezza.KMID[0];
 
512
        dummyitem.len = sizeof(pubk->u.fortezza.KMID);
 
513
        KMID = CERT_Hexify (&dummyitem,0);
 
514
        htmlcertstrings[25] = KMID;
 
515
    } else {
 
516
        /* clear out the headers in the non-fortezza cases */
 
517
        htmlcertstrings[18] = "";
 
518
        htmlcertstrings[19] = "";
 
519
        htmlcertstrings[20] = "";
 
520
        htmlcertstrings[21] = "";
 
521
        htmlcertstrings[22] = "";
 
522
        htmlcertstrings[23] = "";
 
523
        htmlcertstrings[24] = "";
 
524
        htmlcertstrings[25] = "</b>";
 
525
    }
 
526
 
 
527
    if (pubk) {
 
528
      SECKEY_DestroyPublicKey(pubk);
 
529
    }
 
530
 
 
531
#define HTML_OFF 27
 
532
    rv = PK11_HashBuf(SEC_OID_MD5, fingerprint, 
 
533
                      cert->derCert.data, cert->derCert.len);
 
534
    
 
535
    fpitem.data = fingerprint;
 
536
    fpitem.len = sizeof(fingerprint);
 
537
 
 
538
    fpstr = CERT_Hexify (&fpitem,1);
 
539
    
 
540
    htmlcertstrings[HTML_OFF] = fpstr;
 
541
 
 
542
    commentstring = CERT_GetCertCommentString(cert);
 
543
 
 
544
    if (commentstring == NULL) {
 
545
        htmlcertstrings[HTML_OFF+2] = "";
 
546
        htmlcertstrings[HTML_OFF+3] = "";
 
547
        htmlcertstrings[HTML_OFF+4] = "";
 
548
    } else {
 
549
        htmlcertstrings[HTML_OFF+2] =
 
550
            "<b>Comment:</b>"
 
551
            "<table border=0 cellspacing=0 cellpadding=0><tr>"
 
552
            "<td width=10> </td><td><font size=3>"
 
553
            "<textarea name=foobar rows=4 cols=55 onfocus=\"this.blur()\">";
 
554
        htmlcertstrings[HTML_OFF+3] = commentstring;
 
555
        htmlcertstrings[HTML_OFF+4] = "</textarea></font></td></tr></table>";
 
556
    }
 
557
    
 
558
    ret = gatherStrings(htmlcertstrings);
 
559
    
 
560
    if ( issuer ) {
 
561
        PORT_Free(issuer);
 
562
    }
 
563
    
 
564
    if ( subject ) {
 
565
        PORT_Free(subject);
 
566
    }
 
567
    
 
568
    if ( version ) {
 
569
        PORT_Free(version);
 
570
    }
 
571
    
 
572
    if ( serialNumber ) {
 
573
        PORT_Free(serialNumber);
 
574
    }
 
575
    
 
576
    if ( notBefore ) {
 
577
        PORT_Free(notBefore);
 
578
    }
 
579
    
 
580
    if ( notAfter ) {
 
581
        PORT_Free(notAfter);
 
582
    }
 
583
    
 
584
    if ( fpstr ) {
 
585
        PORT_Free(fpstr);
 
586
    }
 
587
    if (DSSPriv) {
 
588
        PORT_Free(DSSPriv);
 
589
    }
 
590
 
 
591
    if (KMID) {
 
592
        PORT_Free(KMID);
 
593
    }
 
594
 
 
595
    if ( commentstring ) {
 
596
        PORT_Free(commentstring);
 
597
    }
 
598
    
 
599
    if ( servername ) {
 
600
        PORT_Free(servername);
 
601
    }
 
602
    
 
603
    return(ret);
 
604
}
 
605