evolution-3.6.4/smime/lib/e-cert.c

Location Tool Test ID Function Issue
e-cert.c:718:3 clang-analyzer Function call argument is an uninitialized value
e-cert.c:718:3 clang-analyzer Function call argument is an uninitialized value
e-cert.c:725:3 clang-analyzer Function call argument is an uninitialized value
e-cert.c:725:3 clang-analyzer Function call argument is an uninitialized value
e-cert.c:1007:10 clang-analyzer Access to field 'avas' results in a dereference of a null pointer
e-cert.c:1007:10 clang-analyzer Access to field 'avas' results in a dereference of a null pointer
   1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
   2 /* The following is the mozilla license blurb, as the bodies some of
   3  * these functions were derived from the mozilla source. */
   4 /*
   5  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
   6  *
   7  * The contents of this file are subject to the Mozilla Public License Version
   8  * 1.1 (the "License"); you may not use this file except in compliance with
   9  * the License. You may obtain a copy of the License at
  10  * http://www.mozilla.org/MPL/
  11  *
  12  * Software distributed under the License is distributed on an "AS IS" basis,
  13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  14  * for the specific language governing rights and limitations under the
  15  * License.
  16  *
  17  * The Original Code is the Netscape security libraries.
  18  *
  19  * The Initial Developer of the Original Code is
  20  * Netscape Communications Corporation.
  21  * Portions created by the Initial Developer are Copyright (C) 1994-2000
  22  * the Initial Developer. All Rights Reserved.
  23  *
  24  * Alternatively, the contents of this file may be used under the terms of
  25  * either the GNU General Public License Version 2 or later (the "GPL"), or
  26  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27  * in which case the provisions of the GPL or the LGPL are applicable instead
  28  * of those above. If you wish to allow use of your version of this file only
  29  * under the terms of either the GPL or the LGPL, and not to allow others to
  30  * use your version of this file under the terms of the MPL, indicate your
  31  * decision by deleting the provisions above and replace them with the notice
  32  * and other provisions required by the GPL or the LGPL. If you do not delete
  33  * the provisions above, a recipient may use your version of this file under
  34  * the terms of any one of the MPL, the GPL or the LGPL.
  35  */
  36 
  37 /*
  38  * Author: Chris Toshok (toshok@ximian.com)
  39  *
  40  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  41  */
  42 #ifdef HAVE_CONFIG_H
  43 #include <config.h>
  44 #endif
  45 
  46 #include <time.h>
  47 
  48 #include <glib/gi18n.h>
  49 
  50 /* for e_utf8_strftime, what about e_time_format_time? */
  51 #include <e-util/e-util.h>
  52 
  53 #include "e-cert.h"
  54 #include "e-cert-trust.h"
  55 #include "pk11func.h"
  56 #include "certdb.h"
  57 #include "hasht.h"
  58 
  59 #define E_CERT_GET_PRIVATE(obj) \
  60 	(G_TYPE_INSTANCE_GET_PRIVATE \
  61 	((obj), E_TYPE_CERT, ECertPrivate))
  62 
  63 struct _ECertPrivate {
  64 	CERTCertificate *cert;
  65 
  66 	/* pointers we cache since the nss implementation allocs the
  67 	 * string */
  68 	gchar *org_name;
  69 	gchar *org_unit_name;
  70 	gchar *cn;
  71 
  72 	gchar *issuer_org_name;
  73 	gchar *issuer_org_unit_name;
  74 	gchar *issuer_cn;
  75 
  76 	PRTime issued_on;
  77 	PRTime expires_on;
  78 
  79 	gchar *issued_on_string;
  80 	gchar *expires_on_string;
  81 
  82 	gchar *serial_number;
  83 
  84 	gchar *usage_string;
  85 
  86 	gchar *sha1_fingerprint;
  87 	gchar *md5_fingerprint;
  88 
  89 	EASN1Object *asn1;
  90 
  91 	gboolean delete;
  92 };
  93 
  94 G_DEFINE_TYPE (ECert, e_cert, G_TYPE_OBJECT)
  95 
  96 static void
  97 e_cert_finalize (GObject *object)
  98 {
  99 	ECertPrivate *priv;
 100 
 101 	priv = E_CERT_GET_PRIVATE (object);
 102 
 103 	if (priv->org_name)
 104 		PORT_Free (priv->org_name);
 105 	if (priv->org_unit_name)
 106 		PORT_Free (priv->org_unit_name);
 107 	if (priv->cn)
 108 		PORT_Free (priv->cn);
 109 
 110 	if (priv->issuer_org_name)
 111 		PORT_Free (priv->issuer_org_name);
 112 	if (priv->issuer_org_unit_name)
 113 		PORT_Free (priv->issuer_org_unit_name);
 114 	if (priv->issuer_cn)
 115 		PORT_Free (priv->issuer_cn);
 116 
 117 	if (priv->issued_on_string)
 118 		PORT_Free (priv->issued_on_string);
 119 	if (priv->expires_on_string)
 120 		PORT_Free (priv->expires_on_string);
 121 	if (priv->serial_number)
 122 		PORT_Free (priv->serial_number);
 123 
 124 	g_free (priv->usage_string);
 125 
 126 	if (priv->sha1_fingerprint)
 127 		PORT_Free (priv->sha1_fingerprint);
 128 	if (priv->md5_fingerprint)
 129 		PORT_Free (priv->md5_fingerprint);
 130 
 131 	if (priv->asn1)
 132 		g_object_unref (priv->asn1);
 133 
 134 	if (priv->delete) {
 135 		printf ("attempting to delete cert marked for deletion\n");
 136 		if (e_cert_get_cert_type (E_CERT (object)) == E_CERT_USER) {
 137 			PK11_DeleteTokenCertAndKey (priv->cert, NULL);
 138 		} else if (!PK11_IsReadOnly (priv->cert->slot)) {
 139 			/* If the list of built-ins does contain a non-removable
 140 			 * copy of this certificate, our call will not remove
 141 			 * the certificate permanently, but rather remove all trust. */
 142 			SEC_DeletePermCertificate (priv->cert);
 143 		}
 144 	}
 145 
 146 	if (priv->cert)
 147 		CERT_DestroyCertificate (priv->cert);
 148 
 149 	/* Chain up to parent's finalize() method. */
 150 	G_OBJECT_CLASS (e_cert_parent_class)->finalize (object);
 151 }
 152 
 153 static void
 154 e_cert_class_init (ECertClass *class)
 155 {
 156 	GObjectClass *object_class;
 157 
 158 	g_type_class_add_private (class, sizeof (ECertPrivate));
 159 
 160 	object_class = G_OBJECT_CLASS (class);
 161 	object_class->finalize = e_cert_finalize;
 162 }
 163 
 164 static void
 165 e_cert_init (ECert *ec)
 166 {
 167 	ec->priv = E_CERT_GET_PRIVATE (ec);
 168 }
 169 
 170 static void
 171 e_cert_populate (ECert *cert)
 172 {
 173 	CERTCertificate *c = cert->priv->cert;
 174 	guchar fingerprint[20];
 175 	SECItem fpItem;
 176 
 177 	cert->priv->org_name = CERT_GetOrgName (&c->subject);
 178 	cert->priv->org_unit_name = CERT_GetOrgUnitName (&c->subject);
 179 
 180 	cert->priv->issuer_org_name = CERT_GetOrgName (&c->issuer);
 181 	cert->priv->issuer_org_unit_name = CERT_GetOrgUnitName (&c->issuer);
 182 
 183 	cert->priv->cn = CERT_GetCommonName (&c->subject);
 184 	cert->priv->issuer_cn = CERT_GetCommonName (&c->issuer);
 185 
 186 	if (SECSuccess == CERT_GetCertTimes (
 187 		c, &cert->priv->issued_on, &cert->priv->expires_on)) {
 188 		PRExplodedTime explodedTime;
 189 		struct tm exploded_tm;
 190 		gchar buf[32];
 191 
 192 		PR_ExplodeTime (
 193 			cert->priv->issued_on,
 194 			PR_LocalTimeParameters, &explodedTime);
 195 		exploded_tm.tm_sec = explodedTime.tm_sec;
 196 		exploded_tm.tm_min = explodedTime.tm_min;
 197 		exploded_tm.tm_hour = explodedTime.tm_hour;
 198 		exploded_tm.tm_mday = explodedTime.tm_mday;
 199 		exploded_tm.tm_mon = explodedTime.tm_month;
 200 		exploded_tm.tm_year = explodedTime.tm_year - 1900;
 201 		e_utf8_strftime (buf, sizeof (buf), _("%d/%m/%Y"), &exploded_tm);
 202 		cert->priv->issued_on_string = g_strdup (buf);
 203 
 204 		PR_ExplodeTime (
 205 			cert->priv->expires_on,
 206 			PR_LocalTimeParameters, &explodedTime);
 207 		exploded_tm.tm_sec = explodedTime.tm_sec;
 208 		exploded_tm.tm_min = explodedTime.tm_min;
 209 		exploded_tm.tm_hour = explodedTime.tm_hour;
 210 		exploded_tm.tm_mday = explodedTime.tm_mday;
 211 		exploded_tm.tm_mon = explodedTime.tm_month;
 212 		exploded_tm.tm_year = explodedTime.tm_year - 1900;
 213 		e_utf8_strftime (buf, sizeof (buf), _("%d/%m/%Y"), &exploded_tm);
 214 		cert->priv->expires_on_string = g_strdup (buf);
 215 	}
 216 
 217 	cert->priv->serial_number = CERT_Hexify (&cert->priv->cert->serialNumber, TRUE);
 218 
 219 	memset (fingerprint, 0, sizeof fingerprint);
 220 	PK11_HashBuf (
 221 		SEC_OID_SHA1, fingerprint,
 222 		cert->priv->cert->derCert.data,
 223 		cert->priv->cert->derCert.len);
 224 	fpItem.data = fingerprint;
 225 	fpItem.len = SHA1_LENGTH;
 226 	cert->priv->sha1_fingerprint = CERT_Hexify (&fpItem, TRUE);
 227 
 228 	memset (fingerprint, 0, sizeof fingerprint);
 229 	PK11_HashBuf (
 230 		SEC_OID_MD5, fingerprint,
 231 		cert->priv->cert->derCert.data,
 232 		cert->priv->cert->derCert.len);
 233 	fpItem.data = fingerprint;
 234 	fpItem.len = MD5_LENGTH;
 235 	cert->priv->md5_fingerprint = CERT_Hexify (&fpItem, TRUE);
 236 }
 237 
 238 ECert *
 239 e_cert_new (CERTCertificate *cert)
 240 {
 241 	ECert *ecert = E_CERT (g_object_new (E_TYPE_CERT, NULL));
 242 
 243 	/* ECert owns a reference to the 'cert', which will be freed on ECert finalize */
 244 	ecert->priv->cert = cert;
 245 
 246 	e_cert_populate (ecert);
 247 
 248 	return ecert;
 249 }
 250 
 251 ECert *
 252 e_cert_new_from_der (gchar *data,
 253                      guint32 len)
 254 {
 255 	CERTCertificate *cert = CERT_DecodeCertFromPackage (data, len);
 256 
 257 	if (!cert)
 258 		return NULL;
 259 
 260 	if (cert->dbhandle == NULL)
 261 		cert->dbhandle = CERT_GetDefaultCertDB ();
 262 
 263 	return e_cert_new (cert);
 264 }
 265 
 266 CERTCertificate *
 267 e_cert_get_internal_cert (ECert *cert)
 268 {
 269 	/* XXX should this refcnt it? */
 270 	return cert->priv->cert;
 271 }
 272 
 273 gboolean
 274 e_cert_get_raw_der (ECert *cert,
 275                     gchar **data,
 276                     guint32 *len)
 277 {
 278 	/* XXX do we really need to check if cert->priv->cert is NULL
 279 	 * here?  it should always be non - null if we have the
 280 	 * ECert.. */
 281 	if (cert->priv->cert) {
 282 		*data = (gchar *)cert->priv->cert->derCert.data;
 283 		*len = (guint32)cert->priv->cert->derCert.len;
 284 		return TRUE;
 285 	}
 286 
 287 	*len = 0;
 288 	return FALSE;
 289 
 290 }
 291 
 292 const gchar *
 293 e_cert_get_window_title (ECert *cert)
 294 {
 295 	if (cert->priv->cert->nickname)
 296 		return cert->priv->cert->nickname;
 297 	else if (cert->priv->cn)
 298 		return cert->priv->cn;
 299 	else
 300 		return cert->priv->cert->subjectName;
 301 }
 302 
 303 const gchar *
 304 e_cert_get_nickname (ECert *cert)
 305 {
 306 	return cert->priv->cert->nickname;
 307 }
 308 
 309 const gchar *
 310 e_cert_get_email (ECert *cert)
 311 {
 312 	return cert->priv->cert->emailAddr;
 313 }
 314 
 315 const gchar *
 316 e_cert_get_org (ECert *cert)
 317 {
 318 	return cert->priv->org_name;
 319 }
 320 
 321 const gchar *
 322 e_cert_get_org_unit (ECert *cert)
 323 {
 324 	return cert->priv->org_unit_name;
 325 }
 326 
 327 const gchar *
 328 e_cert_get_cn (ECert *cert)
 329 {
 330 	return cert->priv->cn;
 331 }
 332 
 333 const gchar *
 334 e_cert_get_issuer_name (ECert *cert)
 335 {
 336 	return cert->priv->cert->issuerName;
 337 }
 338 
 339 const gchar *
 340 e_cert_get_issuer_cn (ECert *cert)
 341 {
 342 	return cert->priv->issuer_cn;
 343 }
 344 
 345 const gchar *
 346 e_cert_get_issuer_org (ECert *cert)
 347 {
 348 	return cert->priv->issuer_org_name;
 349 }
 350 
 351 const gchar *
 352 e_cert_get_issuer_org_unit (ECert *cert)
 353 {
 354 	return cert->priv->issuer_org_unit_name;
 355 }
 356 
 357 const gchar *
 358 e_cert_get_subject_name (ECert *cert)
 359 {
 360 	return cert->priv->cert->subjectName;
 361 }
 362 
 363 PRTime
 364 e_cert_get_issued_on_time (ECert *cert)
 365 {
 366 	return cert->priv->issued_on;
 367 }
 368 
 369 const gchar *
 370 e_cert_get_issued_on (ECert *cert)
 371 {
 372 	return cert->priv->issued_on_string;
 373 }
 374 
 375 PRTime
 376 e_cert_get_expires_on_time (ECert *cert)
 377 {
 378 	return cert->priv->expires_on;
 379 }
 380 
 381 const gchar *
 382 e_cert_get_expires_on (ECert *cert)
 383 {
 384 	return cert->priv->expires_on_string;
 385 }
 386 
 387 static struct {
 388 	gint bit;
 389 	const gchar *text;
 390 } usageinfo[] = {
 391 	/* x509 certificate usage types */
 392 	{ certificateUsageEmailSigner, N_("Sign") },
 393 	{ certificateUsageEmailRecipient, N_("Encrypt") },
 394 };
 395 
 396 const gchar *
 397 e_cert_get_usage (ECert *cert)
 398 {
 399 	if (cert->priv->usage_string == NULL) {
 400 		gint i;
 401 		GString *str = g_string_new ("");
 402 		CERTCertificate *icert = e_cert_get_internal_cert (cert);
 403 
 404 		for (i = 0; i < G_N_ELEMENTS (usageinfo); i++) {
 405 			if (icert->keyUsage & usageinfo[i].bit) {
 406 				if (str->len != 0)
 407 					g_string_append (str, ", ");
 408 				g_string_append (str, _(usageinfo[i].text));
 409 			}
 410 		}
 411 
 412 		cert->priv->usage_string = str->str;
 413 		g_string_free (str, FALSE);
 414 	}
 415 
 416 	return cert->priv->usage_string;
 417 }
 418 
 419 const gchar *
 420 e_cert_get_serial_number (ECert *cert)
 421 {
 422 	return cert->priv->serial_number;
 423 }
 424 
 425 const gchar *
 426 e_cert_get_sha1_fingerprint (ECert *cert)
 427 {
 428 	return cert->priv->sha1_fingerprint;
 429 }
 430 
 431 const gchar *
 432 e_cert_get_md5_fingerprint (ECert *cert)
 433 {
 434 	return cert->priv->md5_fingerprint;
 435 }
 436 
 437 GList *
 438 e_cert_get_chain (ECert *ecert)
 439 {
 440 	GList *l = NULL;
 441 
 442 	g_object_ref (ecert);
 443 
 444 	while (ecert) {
 445 		CERTCertificate *cert = e_cert_get_internal_cert (ecert);
 446 		CERTCertificate *next_cert;
 447 
 448 		l = g_list_append (l, ecert);
 449 
 450 		if (SECITEM_CompareItem (&cert->derIssuer, &cert->derSubject) == SECEqual)
 451 			break;
 452 
 453 		next_cert = CERT_FindCertIssuer (cert, PR_Now (), certUsageSSLClient);
 454 		if (!next_cert)
 455 			break;
 456 
 457 		/* next_cert has a reference already */
 458 		ecert = e_cert_new (next_cert);
 459 	}
 460 
 461 	return l;
 462 }
 463 
 464 ECert *
 465 e_cert_get_ca_cert (ECert *ecert)
 466 {
 467 	CERTCertificate *cert, *next = e_cert_get_internal_cert (ecert), *internal;
 468 
 469 	cert = next;
 470 	internal = cert;
 471 	do {
 472 		if (cert != next && cert != internal)
 473 			CERT_DestroyCertificate (cert);
 474 
 475 		cert = next;
 476 		next = CERT_FindCertIssuer (cert, PR_Now (), certUsageAnyCA);
 477 	} while (next && next != cert);
 478 
 479 	if (cert == internal)
 480 		return g_object_ref (ecert);
 481 	else
 482 		return e_cert_new (cert);
 483 }
 484 
 485 static gboolean
 486 get_int_value (SECItem *versionItem,
 487                gulong *version)
 488 {
 489 	SECStatus srv;
 490 	srv = SEC_ASN1DecodeInteger (versionItem,version);
 491 	if (srv != SECSuccess) {
 492 		g_warning ("could not decode version of cert");
 493 		return FALSE;
 494 	}
 495 	return TRUE;
 496 }
 497 
 498 static gboolean
 499 process_version (SECItem *versionItem,
 500                  EASN1Object **retItem)
 501 {
 502 	EASN1Object *item = e_asn1_object_new ();
 503 	gulong version;
 504 
 505 	e_asn1_object_set_display_name (item, _("Version"));
 506 
 507 	/* Now to figure out what version this certificate is. */
 508 
 509 	if (versionItem->data) {
 510 		if (!get_int_value (versionItem, &version))
 511 			return FALSE;
 512 	} else {
 513 		/* If there is no version present in the cert, then rfc2459
 514 		 * says we default to v1 (0) */
 515 		version = 0;
 516 	}
 517 
 518 	switch (version) {
 519 	case 0:
 520 		e_asn1_object_set_display_value (item, _("Version 1"));
 521 		break;
 522 	case 1:
 523 		e_asn1_object_set_display_value (item, _("Version 2"));
 524 		break;
 525 	case 2:
 526 		e_asn1_object_set_display_value (item, _("Version 3"));
 527 		break;
 528 	default:
 529 		g_warning ("Bad value for cert version");
 530 		return FALSE;
 531 	}
 532 
 533 	*retItem = item;
 534 	return TRUE;
 535 }
 536 
 537 static gboolean
 538 process_serial_number_der (SECItem *serialItem,
 539                            EASN1Object **retItem)
 540 {
 541 	gchar *serialNumber;
 542 	EASN1Object *item = e_asn1_object_new ();
 543 
 544 	e_asn1_object_set_display_name (item, _("Serial Number"));
 545 
 546 	serialNumber = CERT_Hexify (serialItem, 1);
 547 
 548 	e_asn1_object_set_display_value (item, serialNumber);
 549 	PORT_Free (serialNumber); /* XXX the right free to use? */
 550 
 551 	*retItem = item;
 552 	return TRUE;
 553 }
 554 
 555 static gboolean
 556 get_default_oid_format (SECItem *oid,
 557                         gchar **text)
 558 {
 559 	gchar buf[300];
 560 	guint len;
 561 	gint written;
 562 
 563 	gulong val  = oid->data[0];
 564 	guint  i    = val % 40;
 565 	val /= 40;
 566 	written = PR_snprintf (buf, 300, "%lu %u ", val, i);
 567 	if (written < 0)
 568 		return FALSE;
 569 	len = written;
 570 
 571 	val = 0;
 572 	for (i = 1; i < oid->len; ++i) {
 573 		/* In this loop, we have to parse a DER formatted
 574 		 * If the first bit is a 1, then the integer is
 575 		 * represented by more than one byte.  If the
 576 		 * first bit is set then we continue on and add
 577 		 * the values of the later bytes until we get
 578 		 * a byte without the first bit set.
 579 		*/
 580 		gulong j;
 581 
 582 		j = oid->data[i];
 583 		val = (val << 7) | (j & 0x7f);
 584 		if (j & 0x80)
 585 			continue;
 586 		written = PR_snprintf (&buf[len], sizeof (buf) - len, "%lu ", val);
 587 		if (written < 0)
 588 			return FALSE;
 589 
 590 		len += written;
 591 		if (len >= sizeof (buf))
 592 			g_warning ("OID data to big to display in 300 chars.");
 593 		val = 0;
 594   }
 595 
 596   *text = g_strdup (buf);
 597   return TRUE;
 598 }
 599 
 600 static gboolean
 601 get_oid_text (SECItem *oid,
 602               gchar **text)
 603 {
 604 	SECOidTag oidTag = SECOID_FindOIDTag (oid);
 605 	gchar *temp;
 606 
 607 	switch (oidTag) {
 608 	case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
 609 		*text = g_strdup (_("PKCS #1 MD2 With RSA Encryption"));
 610 		break;
 611 	case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
 612 		*text = g_strdup (_("PKCS #1 MD5 With RSA Encryption"));
 613 		break;
 614 	case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
 615 		*text = g_strdup (_("PKCS #1 SHA-1 With RSA Encryption"));
 616 		break;
 617 	case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
 618 		*text = g_strdup (_("PKCS #1 SHA-256 With RSA Encryption"));
 619 		break;
 620 	case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
 621 		*text = g_strdup (_("PKCS #1 SHA-384 With RSA Encryption"));
 622 		break;
 623 	case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
 624 		*text = g_strdup (_("PKCS #1 SHA-512 With RSA Encryption"));
 625 		break;
 626 	case SEC_OID_AVA_COUNTRY_NAME:
 627 		*text = g_strdup ("C");
 628 		break;
 629 	case SEC_OID_AVA_COMMON_NAME:
 630 		*text = g_strdup ("CN");
 631 		break;
 632 	case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
 633 		*text = g_strdup ("OU");
 634 		break;
 635 	case SEC_OID_AVA_ORGANIZATION_NAME:
 636 		*text = g_strdup ("O");
 637 		break;
 638 	case SEC_OID_AVA_LOCALITY:
 639 		*text = g_strdup ("L");
 640 		break;
 641 	case SEC_OID_AVA_DN_QUALIFIER:
 642 		*text = g_strdup ("DN");
 643 		break;
 644 	case SEC_OID_AVA_DC:
 645 		*text = g_strdup ("DC");
 646 		break;
 647 	case SEC_OID_AVA_STATE_OR_PROVINCE:
 648 		*text = g_strdup ("ST");
 649 		break;
 650 	case SEC_OID_PKCS1_RSA_ENCRYPTION:
 651 		*text = g_strdup (_("PKCS #1 RSA Encryption"));
 652 		break;
 653 	case SEC_OID_X509_KEY_USAGE:
 654 		*text = g_strdup (_("Certificate Key Usage"));
 655 		break;
 656 	case SEC_OID_NS_CERT_EXT_CERT_TYPE:
 657 		*text = g_strdup (_("Netscape Certificate Type"));
 658 		break;
 659 	case SEC_OID_X509_AUTH_KEY_ID:
 660 		*text = g_strdup (_("Certificate Authority Key Identifier"));
 661 		break;
 662 	case SEC_OID_RFC1274_UID:
 663 		*text = g_strdup ("UID");
 664 		break;
 665 	case SEC_OID_PKCS9_EMAIL_ADDRESS:
 666 		*text = g_strdup ("E");
 667 		break;
 668 	default:
 669 		if (!get_default_oid_format (oid, &temp))
 670 			return FALSE;
 671 
 672 		*text = g_strdup_printf (_("Object Identifier (%s)"), temp);
 673 		g_free (temp);
 674 
 675 		break;
 676 	}
 677 	return TRUE;
 678 }
 679 
 680 static gboolean
 681 process_raw_bytes (SECItem *data,
 682                    gchar **text)
 683 {
 684 	/* This function is used to display some DER bytes
 685 	 * that we have not added support for decoding.
 686 	 * It prints the value of the byte out into a
 687 	 * string that can later be displayed as a byte
 688 	 * string.  We place a new line after 24 bytes
 689 	 * to break up extermaly long sequence of bytes.
 690 	*/
 691 	GString *str = g_string_new ("");
 692 	PRUint32 i;
 693 	gchar buffer[5];
 694 	for (i = 0; i < data->len; i++) {
 695 		PR_snprintf (buffer, 5, "%02x ", data->data[i]);
 696 		g_string_append (str, buffer);
 697 		if ((i + 1) % 16 == 0) {
 698 			g_string_append (str, "\n");
 699 		}
 700 	}
 701 	*text = g_string_free (str, FALSE);
 702 	return TRUE;
 703 }
 704 
 705 static gboolean
 706 process_sec_algorithm_id (SECAlgorithmID *algID,
 707                           EASN1Object **retSequence)
 708 {
 709 	EASN1Object *sequence = e_asn1_object_new ();
 710 	gchar *text;
 711 
 712 	*retSequence = NULL;
 713 
 714 	get_oid_text (&algID->algorithm, &text);
 715 
 716 	if (!algID->parameters.len ||
 717 		algID->parameters.data[0] == E_ASN1_OBJECT_TYPE_NULL) {
 718 		e_asn1_object_set_display_value (sequence, text);
Function call argument is an uninitialized value
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

Function call argument is an uninitialized value
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

719 e_asn1_object_set_valid_container (sequence, FALSE); 720 } else { 721 EASN1Object *subitem; 722 723 subitem = e_asn1_object_new (); 724 e_asn1_object_set_display_name (subitem, _("Algorithm Identifier")); 725 e_asn1_object_set_display_value (subitem, text);
Function call argument is an uninitialized value
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

Function call argument is an uninitialized value
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

726 e_asn1_object_append_child (sequence, subitem); 727 g_object_unref (subitem); 728 729 g_free (text); 730 731 subitem = e_asn1_object_new (); 732 e_asn1_object_set_display_name (subitem, _("Algorithm Parameters")); 733 process_raw_bytes (&algID->parameters, &text); 734 e_asn1_object_set_display_value (subitem, text); 735 e_asn1_object_append_child (sequence, subitem); 736 g_object_unref (subitem); 737 } 738 739 g_free (text); 740 *retSequence = sequence; 741 return TRUE; 742 } 743 744 static gboolean 745 process_subject_public_key_info (CERTSubjectPublicKeyInfo *spki, 746 EASN1Object *parentSequence) 747 { 748 EASN1Object *spkiSequence = e_asn1_object_new (); 749 EASN1Object *sequenceItem; 750 EASN1Object *printableItem; 751 SECItem data; 752 gchar *text; 753 754 e_asn1_object_set_display_name (spkiSequence, _("Subject Public Key Info")); 755 756 if (!process_sec_algorithm_id (&spki->algorithm, &sequenceItem)) 757 return FALSE; 758 759 e_asn1_object_set_display_name (sequenceItem, _("Subject Public Key Algorithm")); 760 761 e_asn1_object_append_child (spkiSequence, sequenceItem); 762 763 /* The subjectPublicKey field is encoded as a bit string. 764 * ProcessRawBytes expects the lenght to be in bytes, so 765 * let's convert the lenght into a temporary SECItem. 766 */ 767 data.data = spki->subjectPublicKey.data; 768 data.len = spki->subjectPublicKey.len / 8; 769 770 process_raw_bytes (&data, &text); 771 printableItem = e_asn1_object_new (); 772 773 e_asn1_object_set_display_value (printableItem, text); 774 e_asn1_object_set_display_name (printableItem, _("Subject's Public Key")); 775 e_asn1_object_append_child (spkiSequence, printableItem); 776 g_object_unref (printableItem); 777 778 e_asn1_object_append_child (parentSequence, spkiSequence); 779 g_object_unref (spkiSequence); 780 781 return TRUE; 782 } 783 784 static gboolean 785 process_ns_cert_type_extensions (SECItem *extData, 786 GString *text) 787 { 788 SECItem decoded; 789 guchar nsCertType; 790 791 decoded.data = NULL; 792 decoded.len = 0; 793 if (SECSuccess != SEC_ASN1DecodeItem (NULL, &decoded, 794 SEC_ASN1_GET (SEC_BitStringTemplate), extData)) { 795 g_string_append (text, _("Error: Unable to process extension")); 796 return TRUE; 797 } 798 799 nsCertType = decoded.data[0]; 800 801 PORT_Free (decoded.data); /* XXX right free? */ 802 803 if (nsCertType & NS_CERT_TYPE_SSL_CLIENT) { 804 g_string_append (text, _("SSL Client Certificate")); 805 g_string_append (text, "\n"); 806 } 807 if (nsCertType & NS_CERT_TYPE_SSL_SERVER) { 808 g_string_append (text, _("SSL Server Certificate")); 809 g_string_append (text, "\n"); 810 } 811 if (nsCertType & NS_CERT_TYPE_EMAIL) { 812 g_string_append (text, _("Email")); 813 g_string_append (text, "\n"); 814 } 815 if (nsCertType & NS_CERT_TYPE_OBJECT_SIGNING) { 816 g_string_append (text, _("Object Signer")); 817 g_string_append (text, "\n"); 818 } 819 if (nsCertType & NS_CERT_TYPE_SSL_CA) { 820 g_string_append (text, _("SSL Certificate Authority")); 821 g_string_append (text, "\n"); 822 } 823 if (nsCertType & NS_CERT_TYPE_EMAIL_CA) { 824 g_string_append (text, _("Email Certificate Authority")); 825 g_string_append (text, "\n"); 826 } 827 if (nsCertType & NS_CERT_TYPE_OBJECT_SIGNING_CA) { 828 g_string_append (text, _("Object Signer")); 829 g_string_append (text, "\n"); 830 } 831 return TRUE; 832 } 833 834 static gboolean 835 process_key_usage_extensions (SECItem *extData, 836 GString *text) 837 { 838 SECItem decoded; 839 guchar keyUsage; 840 841 decoded.data = NULL; 842 decoded.len = 0; 843 if (SECSuccess != SEC_ASN1DecodeItem (NULL, &decoded, 844 SEC_ASN1_GET (SEC_BitStringTemplate), extData)) { 845 g_string_append (text, _("Error: Unable to process extension")); 846 return TRUE; 847 } 848 849 keyUsage = decoded.data[0]; 850 PORT_Free (decoded.data); /* XXX right free? */ 851 852 if (keyUsage & KU_DIGITAL_SIGNATURE) { 853 g_string_append (text, _("Signing")); 854 g_string_append (text, "\n"); 855 } 856 if (keyUsage & KU_NON_REPUDIATION) { 857 g_string_append (text, _("Non-repudiation")); 858 g_string_append (text, "\n"); 859 } 860 if (keyUsage & KU_KEY_ENCIPHERMENT) { 861 g_string_append (text, _("Key Encipherment")); 862 g_string_append (text, "\n"); 863 } 864 if (keyUsage & KU_DATA_ENCIPHERMENT) { 865 g_string_append (text, _("Data Encipherment")); 866 g_string_append (text, "\n"); 867 } 868 if (keyUsage & KU_KEY_AGREEMENT) { 869 g_string_append (text, _("Key Agreement")); 870 g_string_append (text, "\n"); 871 } 872 if (keyUsage & KU_KEY_CERT_SIGN) { 873 g_string_append (text, _("Certificate Signer")); 874 g_string_append (text, "\n"); 875 } 876 if (keyUsage & KU_CRL_SIGN) { 877 g_string_append (text, _("CRL Signer")); 878 g_string_append (text, "\n"); 879 } 880 881 return TRUE; 882 } 883 884 static gboolean 885 process_extension_data (SECOidTag oidTag, 886 SECItem *extData, 887 GString *str) 888 { 889 gboolean rv; 890 switch (oidTag) { 891 case SEC_OID_NS_CERT_EXT_CERT_TYPE: 892 rv = process_ns_cert_type_extensions (extData, str); 893 break; 894 case SEC_OID_X509_KEY_USAGE: 895 rv = process_key_usage_extensions (extData, str); 896 break; 897 default: { 898 gchar *text; 899 rv = process_raw_bytes (extData, &text); 900 g_string_append (str, text); 901 g_free (text); 902 break; 903 } 904 } 905 return rv; 906 } 907 908 static gboolean 909 process_single_extension (CERTCertExtension *extension, 910 EASN1Object **retExtension) 911 { 912 GString *str = g_string_new (""); 913 gchar *text; 914 EASN1Object *extensionItem; 915 SECOidTag oidTag = SECOID_FindOIDTag (&extension->id); 916 917 get_oid_text (&extension->id, &text); 918 919 extensionItem = e_asn1_object_new (); 920 921 e_asn1_object_set_display_name (extensionItem, text); 922 g_free (text); 923 924 if (extension->critical.data != NULL) { 925 if (extension->critical.data[0]) { 926 g_string_append (str, _("Critical")); 927 } else { 928 g_string_append (str, _("Not Critical")); 929 } 930 } else { 931 g_string_append (str, _("Not Critical")); 932 } 933 g_string_append (str, "\n"); 934 if (!process_extension_data (oidTag, &extension->value, str)) { 935 g_string_free (str, TRUE); 936 return FALSE; 937 } 938 939 e_asn1_object_set_display_value (extensionItem, str->str); 940 g_string_free (str, TRUE); 941 *retExtension = extensionItem; 942 return TRUE; 943 } 944 945 static gboolean 946 process_extensions (CERTCertExtension **extensions, 947 EASN1Object *parentSequence) 948 { 949 EASN1Object *extensionSequence = e_asn1_object_new (); 950 PRInt32 i; 951 952 e_asn1_object_set_display_name (extensionSequence, _("Extensions")); 953 954 for (i = 0; extensions[i] != NULL; i++) { 955 EASN1Object *newExtension; 956 957 if (!process_single_extension (extensions[i], 958 &newExtension)) 959 return FALSE; 960 961 e_asn1_object_append_child (extensionSequence, newExtension); 962 } 963 e_asn1_object_append_child (parentSequence, extensionSequence); 964 return TRUE; 965 } 966 967 static gboolean 968 process_name (CERTName *name, 969 gchar **value) 970 { 971 CERTRDN ** rdns; 972 CERTRDN ** rdn; 973 CERTAVA ** avas; 974 CERTAVA * ava; 975 SECItem *decodeItem = NULL; 976 GString *final_string = g_string_new (""); 977 978 gchar *type; 979 GString *avavalue; 980 gchar *temp; 981 CERTRDN **lastRdn; 982 983 rdns = name->rdns; 984 985 /* find last RDN */ 986 lastRdn = rdns; 987 while (*lastRdn) lastRdn++; 988 989 /* The above whille loop will put us at the last member 990 * of the array which is a NULL pointer. So let's back 991 * up one spot so that we have the last non-NULL entry in 992 * the array in preparation for traversing the 993 * RDN's (Relative Distinguished Name) in reverse order. 994 */ 995 lastRdn--; 996 997 /* 998 * Loop over name contents in _reverse_ RDN order appending to string 999 * When building the Ascii string, NSS loops over these entries in 1000 * reverse order, so I will as well. The difference is that NSS 1001 * will always place them in a one line string separated by commas, 1002 * where I want each entry on a single line. I can't just use a comma 1003 * as my delimitter because it is a valid character to have in the 1004 * value portion of the AVA and could cause trouble when parsing. 1005 */ 1006 for (rdn = lastRdn; rdn >= rdns; rdn--) { 1007 avas = (*rdn)->avas;
Access to field 'avas' results in a dereference of a null pointer
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

Access to field 'avas' results in a dereference of a null pointer
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

1008 while ((ava = *avas++) != 0) { 1009 if (!get_oid_text (&ava->type, &type)) 1010 return FALSE; 1011 1012 /* This function returns a string in UTF8 format. */ 1013 decodeItem = CERT_DecodeAVAValue (&ava->value); 1014 if (!decodeItem) { 1015 return FALSE; 1016 } 1017 1018 avavalue = g_string_new_len ( 1019 (gchar *) decodeItem->data, decodeItem->len); 1020 1021 SECITEM_FreeItem (decodeItem, PR_TRUE); 1022 1023 /* Translators: This string is used in Certificate 1024 * details for fields like Issuer or Subject, which 1025 * shows the field name on the left and its respective 1026 * value on the right, both as stored in the 1027 * certificate itself. You probably do not need to 1028 * change this string, unless changing the order of 1029 * name and value. As a result example: 1030 * "OU = VeriSign Trust Network" */ 1031 temp = g_strdup_printf (_("%s = %s"), type, avavalue->str); 1032 1033 g_string_append (final_string, temp); 1034 g_string_append (final_string, "\n"); 1035 g_string_free (avavalue, TRUE); 1036 g_free (temp); 1037 } 1038 } 1039 *value = g_string_free (final_string, FALSE); 1040 return TRUE; 1041 } 1042 1043 static gboolean 1044 create_tbs_certificate_asn1_struct (ECert *cert, 1045 EASN1Object **seq) 1046 { 1047 /* 1048 ** TBSCertificate ::= SEQUENCE { 1049 ** version [0] EXPLICIT Version DEFAULT v1, 1050 ** serialNumber CertificateSerialNumber, 1051 ** signature AlgorithmIdentifier, 1052 ** issuer Name, 1053 ** validity Validity, 1054 ** subject Name, 1055 ** subjectPublicKeyInfo SubjectPublicKeyInfo, 1056 ** issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, 1057 ** -- If present, version shall be v2 or v3 1058 ** subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, 1059 ** -- If present, version shall be v2 or v3 1060 ** extensions [3] EXPLICIT Extensions OPTIONAL 1061 ** -- If present, version shall be v3 1062 ** } 1063 ** 1064 ** This is the ASN1 structure we should be dealing with at this point. 1065 ** The code in this method will assert this is the structure we're dealing 1066 ** and then add more user friendly text for that field. 1067 */ 1068 EASN1Object *sequence = e_asn1_object_new (); 1069 gchar *text; 1070 EASN1Object *subitem; 1071 SECItem data; 1072 1073 e_asn1_object_set_display_name (sequence, _("Certificate")); 1074 1075 if (!process_version (&cert->priv->cert->version, &subitem)) 1076 return FALSE; 1077 e_asn1_object_append_child (sequence, subitem); 1078 g_object_unref (subitem); 1079 1080 if (!process_serial_number_der (&cert->priv->cert->serialNumber, &subitem)) 1081 return FALSE; 1082 e_asn1_object_append_child (sequence, subitem); 1083 g_object_unref (subitem); 1084 1085 if (!process_sec_algorithm_id (&cert->priv->cert->signature, &subitem)) 1086 return FALSE; 1087 e_asn1_object_set_display_name (subitem, _("Certificate Signature Algorithm")); 1088 e_asn1_object_append_child (sequence, subitem); 1089 g_object_unref (subitem); 1090 1091 process_name (&cert->priv->cert->issuer, &text); 1092 subitem = e_asn1_object_new (); 1093 e_asn1_object_set_display_value (subitem, text); 1094 g_free (text); 1095 1096 e_asn1_object_set_display_name (subitem, _("Issuer")); 1097 e_asn1_object_append_child (sequence, subitem); 1098 g_object_unref (subitem); 1099 1100 #ifdef notyet 1101 nsCOMPtr < nsIASN1Sequence> validitySequence = new nsNSSASN1Sequence (); 1102 nssComponent->GetPIPNSSBundleString (NS_LITERAL_STRING ("CertDumpValidity").get (), 1103 text); 1104 validitySequence->SetDisplayName (text); 1105 asn1Objects->AppendElement (validitySequence, PR_FALSE); 1106 nssComponent->GetPIPNSSBundleString (NS_LITERAL_STRING ("CertDumpNotBefore").get (), 1107 text); 1108 nsCOMPtr < nsIX509CertValidity> validityData; 1109 GetValidity (getter_AddRefs (validityData)); 1110 PRTime notBefore, notAfter; 1111 1112 validityData->GetNotBefore (&notBefore); 1113 validityData->GetNotAfter (&notAfter); 1114 validityData = 0; 1115 rv = ProcessTime (notBefore, text.get (), validitySequence); 1116 if (NS_FAILED (rv)) 1117 return rv; 1118 1119 nssComponent->GetPIPNSSBundleString (NS_LITERAL_STRING ("CertDumpNotAfter").get (), 1120 text); 1121 rv = ProcessTime (notAfter, text.get (), validitySequence); 1122 if (NS_FAILED (rv)) 1123 return rv; 1124 #endif 1125 1126 subitem = e_asn1_object_new (); 1127 e_asn1_object_set_display_name (subitem, _("Subject")); 1128 1129 process_name (&cert->priv->cert->subject, &text); 1130 e_asn1_object_set_display_value (subitem, text); 1131 g_free (text); 1132 e_asn1_object_append_child (sequence, subitem); 1133 g_object_unref (subitem); 1134 1135 if (!process_subject_public_key_info ( 1136 &cert->priv->cert->subjectPublicKeyInfo, sequence)) 1137 return FALSE; 1138 1139 /* Is there an issuerUniqueID? */ 1140 if (cert->priv->cert->issuerID.data) { 1141 /* The issuerID is encoded as a bit string. 1142 * The function ProcessRawBytes expects the 1143 * length to be in bytes, so let's convert the 1144 * length in a temporary SECItem 1145 */ 1146 data.data = cert->priv->cert->issuerID.data; 1147 data.len = cert->priv->cert->issuerID.len / 8; 1148 1149 subitem = e_asn1_object_new (); 1150 1151 e_asn1_object_set_display_name (subitem, _("Issuer Unique ID")); 1152 process_raw_bytes (&data, &text); 1153 e_asn1_object_set_display_value (subitem, text); 1154 g_free (text); 1155 1156 e_asn1_object_append_child (sequence, subitem); 1157 } 1158 1159 if (cert->priv->cert->subjectID.data) { 1160 /* The subjectID is encoded as a bit string. 1161 * The function ProcessRawBytes expects the 1162 * length to be in bytes, so let's convert the 1163 * length in a temporary SECItem 1164 */ 1165 data.data = cert->priv->cert->issuerID.data; 1166 data.len = cert->priv->cert->issuerID.len / 8; 1167 1168 subitem = e_asn1_object_new (); 1169 1170 e_asn1_object_set_display_name (subitem, _("Subject Unique ID")); 1171 process_raw_bytes (&data, &text); 1172 e_asn1_object_set_display_value (subitem, text); 1173 g_free (text); 1174 1175 e_asn1_object_append_child (sequence, subitem); 1176 } 1177 if (cert->priv->cert->extensions) { 1178 if (!process_extensions (cert->priv->cert->extensions, sequence)) 1179 return FALSE; 1180 } 1181 1182 *seq = sequence; 1183 1184 return TRUE; 1185 } 1186 1187 static gboolean 1188 create_asn1_struct (ECert *cert) 1189 { 1190 EASN1Object *sequence; 1191 SECItem temp; 1192 gchar *text; 1193 1194 cert->priv->asn1 = e_asn1_object_new (); 1195 1196 e_asn1_object_set_display_name (cert->priv->asn1, e_cert_get_window_title (cert)); 1197 1198 /* This sequence will be contain the tbsCertificate, signatureAlgorithm, 1199 * and signatureValue. */ 1200 1201 if (!create_tbs_certificate_asn1_struct (cert, &sequence)) 1202 return FALSE; 1203 e_asn1_object_append_child (cert->priv->asn1, sequence); 1204 g_object_unref (sequence); 1205 1206 if (!process_sec_algorithm_id ( 1207 &cert->priv->cert->signatureWrap.signatureAlgorithm, &sequence)) 1208 return FALSE; 1209 e_asn1_object_set_display_name ( 1210 sequence, _("Certificate Signature Algorithm")); 1211 e_asn1_object_append_child (cert->priv->asn1, sequence); 1212 g_object_unref (sequence); 1213 1214 sequence = e_asn1_object_new (); 1215 e_asn1_object_set_display_name ( 1216 sequence, _("Certificate Signature Value")); 1217 1218 /* The signatureWrap is encoded as a bit string. 1219 * The function ProcessRawBytes expects the 1220 * length to be in bytes, so let's convert the 1221 * length in a temporary SECItem */ 1222 temp.data = cert->priv->cert->signatureWrap.signature.data; 1223 temp.len = cert->priv->cert->signatureWrap.signature.len / 8; 1224 process_raw_bytes (&temp, &text); 1225 e_asn1_object_set_display_value (sequence, text); 1226 e_asn1_object_append_child (cert->priv->asn1, sequence); 1227 g_free (text); 1228 1229 return TRUE; 1230 } 1231 1232 EASN1Object * 1233 e_cert_get_asn1_struct (ECert *cert) 1234 { 1235 if (!cert->priv->asn1) 1236 create_asn1_struct (cert); 1237 1238 return g_object_ref (cert->priv->asn1); 1239 } 1240 1241 gboolean 1242 e_cert_mark_for_deletion (ECert *cert) 1243 { 1244 /* nsNSSShutDownPreventionLock locker; */ 1245 1246 #if 0 1247 /* make sure user is logged in to the token */ 1248 nsCOMPtr < nsIInterfaceRequestor> ctx = new PipUIContext (); 1249 #endif 1250 1251 if (PK11_NeedLogin (cert->priv->cert->slot) 1252 && !PK11_NeedUserInit (cert->priv->cert->slot) 1253 && !PK11_IsInternal (cert->priv->cert->slot)) { 1254 if (PK11_Authenticate ( 1255 cert->priv->cert->slot, PR_TRUE, NULL) != SECSuccess) { 1256 return FALSE; 1257 } 1258 } 1259 1260 cert->priv->delete = TRUE; 1261 1262 return TRUE; 1263 } 1264 1265 ECertType 1266 e_cert_get_cert_type (ECert *ecert) 1267 { 1268 const gchar *nick = e_cert_get_nickname (ecert); 1269 const gchar *email = e_cert_get_email (ecert); 1270 CERTCertificate *cert = ecert->priv->cert; 1271 1272 if (nick) { 1273 if (e_cert_trust_has_any_user (cert->trust)) 1274 return E_CERT_USER; 1275 if (e_cert_trust_has_any_ca (cert->trust) 1276 || CERT_IsCACert (cert,NULL)) 1277 return E_CERT_CA; 1278 if (e_cert_trust_has_peer (cert->trust, PR_TRUE, PR_FALSE, PR_FALSE)) 1279 return E_CERT_SITE; 1280 } 1281 if (email && e_cert_trust_has_peer (cert->trust, PR_FALSE, PR_TRUE, PR_FALSE)) 1282 return E_CERT_CONTACT; 1283 1284 return E_CERT_UNKNOWN; 1285 }