Home | History | Annotate | Line # | Download | only in efi
certs.c revision 1.4
      1  1.4  riastrad /* $NetBSD: certs.c,v 1.4 2025/03/02 00:03:41 riastradh Exp $ */
      2  1.1  christos 
      3  1.1  christos /*
      4  1.1  christos  * Redistribution and use in source and binary forms, with or without
      5  1.1  christos  * modification, are permitted provided that the following conditions
      6  1.1  christos  * are met:
      7  1.1  christos  * 1. Redistributions of source code must retain the above copyright
      8  1.1  christos  *    notice, this list of conditions and the following disclaimer.
      9  1.1  christos  * 2. Redistributions in binary form must reproduce the above copyright
     10  1.1  christos  *    notice, this list of conditions and the following disclaimer in the
     11  1.1  christos  *    documentation and/or other materials provided with the distribution.
     12  1.1  christos  *
     13  1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     14  1.1  christos  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     15  1.1  christos  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     16  1.1  christos  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     17  1.1  christos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     18  1.1  christos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     19  1.1  christos  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     20  1.1  christos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     21  1.1  christos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     22  1.1  christos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     23  1.1  christos  * SUCH DAMAGE.
     24  1.1  christos  */
     25  1.1  christos 
     26  1.1  christos #include <sys/cdefs.h>
     27  1.1  christos #ifndef lint
     28  1.4  riastrad __RCSID("$NetBSD: certs.c,v 1.4 2025/03/02 00:03:41 riastradh Exp $");
     29  1.1  christos #endif /* not lint */
     30  1.1  christos 
     31  1.1  christos #include <assert.h>
     32  1.1  christos #include <stdbool.h>
     33  1.1  christos #include <stdio.h>
     34  1.1  christos #include <stdlib.h>
     35  1.1  christos #include <sys/efiio.h>
     36  1.1  christos 
     37  1.1  christos #include "efiio.h"
     38  1.1  christos #include "defs.h"
     39  1.1  christos #include "certs.h"
     40  1.1  christos 
     41  1.1  christos /*
     42  1.1  christos  * See UEFI spec section 32.4
     43  1.1  christos  */
     44  1.1  christos 
     45  1.1  christos #define EFI_CERT_SHA256_GUID \
     46  1.2    rillig 	{0xc1c41626,0x504c,0x4092,0xac,0xa9,\
     47  1.2    rillig  	  {0x41,0xf9,0x36,0x93,0x43,0x28}}
     48  1.1  christos 
     49  1.1  christos #define EFI_CERT_RSA2048_GUID \
     50  1.2    rillig 	{0x3c5766e8,0x269c,0x4e34,0xaa,0x14,\
     51  1.2    rillig 	  {0xed,0x77,0x6e,0x85,0xb3,0xb6}}
     52  1.1  christos 
     53  1.1  christos #define EFI_CERT_RSA2048_SHA256_GUID \
     54  1.2    rillig 	{0xe2b36190,0x879b,0x4a3d,0xad,0x8d,\
     55  1.2    rillig 	  {0xf2,0xe7,0xbb,0xa3,0x27,0x84}}
     56  1.1  christos 
     57  1.1  christos #define EFI_CERT_SHA1_GUID \
     58  1.2    rillig 	{0x826ca512,0xcf10,0x4ac9,0xb1,0x87,\
     59  1.2    rillig 	  {0xbe,0x01,0x49,0x66,0x31,0xbd}}
     60  1.1  christos 
     61  1.1  christos #define EFI_CERT_RSA2048_SHA1_GUID \
     62  1.2    rillig 	{0x67f8444f,0x8743,0x48f1,0xa3,0x28,\
     63  1.2    rillig 	  {0x1e,0xaa,0xb8,0x73,0x60,0x80}}
     64  1.1  christos 
     65  1.1  christos #define EFI_CERT_X509_GUID \
     66  1.2    rillig 	{0xa5c059a1,0x94e4,0x4aa7,0x87,0xb5,\
     67  1.2    rillig 	  {0xab,0x15,0x5c,0x2b,0xf0,0x72}}
     68  1.1  christos 
     69  1.1  christos #define EFI_CERT_SHA224_GUID \
     70  1.2    rillig 	{0x0b6e5233,0xa65c,0x44c9,0x94,0x07,\
     71  1.2    rillig 	  {0xd9,0xab,0x83,0xbf,0xc8,0xbd}}
     72  1.1  christos 
     73  1.1  christos #define EFI_CERT_SHA384_GUID \
     74  1.2    rillig 	{0xff3e5307,0x9fd0,0x48c9,0x85,0xf1,\
     75  1.2    rillig 	  {0x8a,0xd5,0x6c,0x70,0x1e,0x01}}
     76  1.1  christos 
     77  1.1  christos #define EFI_CERT_SHA512_GUID \
     78  1.2    rillig 	{0x093e0fae,0xa6c4,0x4f50,0x9f,0x1b,\
     79  1.2    rillig 	  {0xd4,0x1e,0x2b,0x89,0xc1,0x9a}}
     80  1.1  christos 
     81  1.1  christos #define EFI_CERT_X509_SHA256_GUID \
     82  1.2    rillig 	{0x3bd2a492,0x96c0,0x4079,0xb4,0x20,\
     83  1.2    rillig 	  {0xfc,0xf9,0x8e,0xf1,0x03,0xed}}
     84  1.1  christos 
     85  1.1  christos #define EFI_CERT_X509_SHA384_GUID \
     86  1.2    rillig 	{0x7076876e,0x80c2,0x4ee6,0xaa,0xd2,\
     87  1.2    rillig 	  {0x28,0xb3,0x49,0xa6,0x86,0x5b}}
     88  1.1  christos 
     89  1.1  christos #define EFI_CERT_X509_SHA512_GUID \
     90  1.2    rillig 	{0x446dbf63,0x2502,0x4cda,0xbc,0xfa,\
     91  1.2    rillig 	  {0x24,0x65,0xd2,0xb0,0xfe,0x9d}}
     92  1.1  christos 
     93  1.1  christos #define EFI_CERT_EXTERNAL_MANAGEMENT_GUID \
     94  1.2    rillig 	{0x452e8ced,0xdfff,0x4b8c,0xae,0x01,\
     95  1.2    rillig 	  {0x51,0x18,0x86,0x2e,0x68,0x2c}}
     96  1.1  christos 
     97  1.1  christos #define EFI_CERT_GUIDS \
     98  1.1  christos   _X(SHA256,		sigfn0, 	16 + 32)  \
     99  1.1  christos   _X(RSA2048,		sigfn0, 	16 + 256) \
    100  1.1  christos   _X(RSA2048_SHA256,	sigfn0, 	16 + 256) \
    101  1.1  christos   _X(SHA1,		sigfn0, 	16 + 20)  \
    102  1.1  christos   _X(RSA2048_SHA1,	sigfn0, 	16 + 256) \
    103  1.1  christos   _X(X509,		sigfn0, 	0)	  \
    104  1.1  christos   _X(SHA224,		sigfn0, 	16 + 28)  \
    105  1.1  christos   _X(SHA384,		sigfn0, 	16 + 48)  \
    106  1.1  christos   _X(SHA512,		sigfn0, 	16 + 64)  \
    107  1.1  christos   _X(X509_SHA256,	sigfn256,	16 + 48)  \
    108  1.1  christos   _X(X509_SHA384,	sigfn384,	16 + 64)  \
    109  1.1  christos   _X(X509_SHA512,	sigfn512,	16 + 80)  \
    110  1.1  christos   _X(EXTERNAL_MANAGEMENT, sigfn1,	16 + 1)
    111  1.1  christos 
    112  1.1  christos #define EFI_CERT_GUID_UNKNOWN	"unknown"
    113  1.1  christos 
    114  1.1  christos /************************************************************************/
    115  1.1  christos 
    116  1.1  christos typedef uint8_t EFI_SHA256_HASH[32];
    117  1.1  christos typedef uint8_t EFI_SHA384_HASH[48];
    118  1.1  christos typedef uint8_t EFI_SHA512_HASH[64];
    119  1.1  christos 
    120  1.1  christos typedef struct EFI_SIGNATURE_DAT {
    121  1.1  christos 	uuid_t			SignatureOwner;
    122  1.1  christos 	uint8_t			SignatureData[];
    123  1.1  christos } __packed EFI_SIGNATURE_DATA_t;
    124  1.1  christos 
    125  1.1  christos typedef struct EFI_SIGNATURE_LIST {
    126  1.1  christos 	uuid_t			SignatureType;
    127  1.1  christos 	uint32_t		SignatureListSize;
    128  1.1  christos 	uint32_t		SignatureHeaderSize;
    129  1.1  christos 	uint32_t		SignatureSize;
    130  1.1  christos 	uint8_t			SignatureListBody[];
    131  1.1  christos //	uint8_t			SignatureHeader[SignatureHeaderSize];
    132  1.1  christos //	EFI_SIGNATURE_DATA	Signatures[][SignatureSize];
    133  1.1  christos } __packed EFI_SIGNATURE_LIST_t;
    134  1.1  christos 
    135  1.1  christos typedef struct {
    136  1.1  christos 	uint16_t	Year;		// 1900 - 9999
    137  1.1  christos 	uint8_t		Month;		// 1 - 12
    138  1.1  christos 	uint8_t		Day;		// 1 - 31
    139  1.1  christos 	uint8_t		Hour;		// 0 - 23
    140  1.1  christos 	uint8_t		Minute;		// 0 - 59
    141  1.1  christos 	uint8_t		Second;		// 0 - 59
    142  1.1  christos 	uint8_t		Pad1;
    143  1.1  christos 	uint32_t	Nanosecond;	// 0 - 999,999,999
    144  1.1  christos 	int16_t		TimeZone;	// -1440 to 1440 or 2047 (0x7ff)
    145  1.1  christos #define EFI_UNSPECIFIED_TIMEZONE	0x07FF
    146  1.1  christos 	uint8_t		Daylight;
    147  1.1  christos #define EFI_TIME_ADJUST_DAYLIGHT	0x01
    148  1.1  christos #define EFI_TIME_IN_DAYLIGHT		0x02
    149  1.1  christos 	uint8_t		Pad2;
    150  1.1  christos } __packed EFI_TIME;
    151  1.1  christos 
    152  1.1  christos /************************************************************************/
    153  1.1  christos 
    154  1.1  christos static char *
    155  1.1  christos show_time(const EFI_TIME *et, int indent)
    156  1.1  christos {
    157  1.1  christos 	/*
    158  1.1  christos 	 * XXX: Deal with the Daylight flags!
    159  1.1  christos 	 */
    160  1.1  christos 	printf("%*s%u.%u.%u %u:%u:%u.%u",
    161  1.1  christos 	    indent, "",
    162  1.1  christos 	    et->Year,
    163  1.1  christos 	    et->Month,
    164  1.1  christos 	    et->Day,
    165  1.1  christos 	    et->Hour,
    166  1.1  christos 	    et->Minute,
    167  1.1  christos 	    et->Second,
    168  1.1  christos 	    et->Nanosecond);
    169  1.1  christos 	if (et->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
    170  1.1  christos 		printf(" (%d)", et->TimeZone);
    171  1.1  christos 	}
    172  1.1  christos 	printf("\n");
    173  1.1  christos 
    174  1.1  christos 	return NULL;
    175  1.1  christos }
    176  1.1  christos 
    177  1.1  christos /************************************************************************/
    178  1.1  christos 
    179  1.1  christos static int
    180  1.1  christos sigfn0(const void *vp, size_t sz, int indent)
    181  1.1  christos {
    182  1.1  christos 	const struct {
    183  1.1  christos 		uuid_t	uuid;
    184  1.1  christos 		uint8_t data[];
    185  1.1  christos 	} __packed *s = vp;
    186  1.1  christos 
    187  1.1  christos 	printf("%*sOwner: ", indent, "");
    188  1.1  christos 	uuid_printf(&s->uuid);
    189  1.1  christos 	printf("\n");
    190  1.1  christos 	show_data(s->data, sz, "  ");
    191  1.1  christos 	return 0;
    192  1.1  christos }
    193  1.1  christos 
    194  1.1  christos static int
    195  1.1  christos sigfn1(const void *vp, size_t sz, int indent)
    196  1.1  christos {
    197  1.1  christos 	const struct {
    198  1.1  christos 		uuid_t uuid;
    199  1.1  christos 		uint8_t zero;
    200  1.1  christos 	} __packed *s = vp;
    201  1.1  christos 
    202  1.1  christos 	assert(sizeof(*s) == sizeof(s->uuid) + sz);
    203  1.1  christos 	printf("%*sOwner: ", indent, "");
    204  1.1  christos 	uuid_printf(&s->uuid);
    205  1.1  christos 	printf("\n");
    206  1.1  christos 	printf("%*szero: 0x%02x\n", indent, "", s->zero);
    207  1.1  christos 	return 0;
    208  1.1  christos }
    209  1.1  christos 
    210  1.1  christos static int
    211  1.1  christos sigfn256(const void *vp, size_t sz, int indent)
    212  1.1  christos {
    213  1.1  christos 	const struct {
    214  1.1  christos 		uuid_t uuid;
    215  1.1  christos 		EFI_SHA256_HASH		ToBeSignedHash;
    216  1.1  christos 		EFI_TIME		TimeOfRevocation;
    217  1.1  christos 	} __packed *s = vp;
    218  1.1  christos 
    219  1.1  christos 	assert(sizeof(*s) == sizeof(s->uuid) + sz);
    220  1.1  christos 	printf("%*sOwner: ", indent, "");
    221  1.1  christos 	uuid_printf(&s->uuid);
    222  1.1  christos 	printf("\n");
    223  1.3  christos 	show_data((const void *)&s->ToBeSignedHash, sizeof(s->ToBeSignedHash),
    224  1.3  christos 	    "  ");
    225  1.1  christos 	printf("%*sTimeOfRevocation: ", indent, "");
    226  1.1  christos 	show_time(&s->TimeOfRevocation, indent);
    227  1.1  christos 	return 0;
    228  1.1  christos }
    229  1.1  christos 
    230  1.1  christos static int
    231  1.1  christos sigfn384(const void *vp, size_t sz, int indent)
    232  1.1  christos {
    233  1.1  christos 	const struct {
    234  1.1  christos 		uuid_t uuid;
    235  1.1  christos 		EFI_SHA384_HASH		ToBeSignedHash;
    236  1.1  christos 		EFI_TIME		TimeOfRevocation;
    237  1.1  christos 	} __packed *s = vp;
    238  1.1  christos 
    239  1.1  christos 	assert(sizeof(*s) == sizeof(s->uuid) + sz);
    240  1.1  christos 	printf("%*sOwner: ", indent, "");
    241  1.1  christos 	uuid_printf(&s->uuid);
    242  1.1  christos 	printf("\n");
    243  1.3  christos 	show_data((const void *)&s->ToBeSignedHash, sizeof(s->ToBeSignedHash),
    244  1.3  christos 	    "  ");
    245  1.1  christos 	printf("%*sTimeOfRevocation: ", indent, "");
    246  1.1  christos 	show_time(&s->TimeOfRevocation, indent);
    247  1.1  christos 	return 0;
    248  1.1  christos }
    249  1.1  christos 
    250  1.1  christos static int
    251  1.1  christos sigfn512(const void *vp, size_t sz, int indent)
    252  1.1  christos {
    253  1.1  christos 	const struct {
    254  1.1  christos 		uuid_t uuid;
    255  1.1  christos 		EFI_SHA512_HASH		ToBeSignedHash;
    256  1.1  christos 		EFI_TIME		TimeOfRevocation;
    257  1.1  christos 	} __packed *s = vp;
    258  1.1  christos 
    259  1.1  christos 	assert(sizeof(*s) == sizeof(s->uuid) + sz);
    260  1.1  christos 	printf("%*sOwner: ", indent, "");
    261  1.1  christos 	uuid_printf(&s->uuid);
    262  1.1  christos 	printf("\n");
    263  1.3  christos 	show_data((const void *)&s->ToBeSignedHash, sizeof(s->ToBeSignedHash),
    264  1.3  christos 	    "  ");
    265  1.1  christos 	printf("%*sTimeOfRevocation: ", indent, "");
    266  1.1  christos 	show_time(&s->TimeOfRevocation, indent);
    267  1.1  christos 	return 0;
    268  1.1  christos }
    269  1.1  christos 
    270  1.1  christos /************************************************************************/
    271  1.1  christos 
    272  1.1  christos struct cert_tbl {
    273  1.1  christos 	uuid_t guid;
    274  1.1  christos 	const char *name;
    275  1.1  christos 	int (*sigfn)(const void *, size_t, int);
    276  1.1  christos 	size_t sigsz;
    277  1.1  christos };
    278  1.1  christos 
    279  1.1  christos static int
    280  1.1  christos sortcmpfn(const void *a, const void *b)
    281  1.1  christos {
    282  1.1  christos 	const struct cert_tbl *p = a;
    283  1.1  christos 	const struct cert_tbl *q = b;
    284  1.1  christos 
    285  1.1  christos 	return memcmp(&p->guid, &q->guid, sizeof(p->guid));
    286  1.1  christos }
    287  1.1  christos 
    288  1.1  christos static int
    289  1.1  christos srchcmpfn(const void *a, const void *b)
    290  1.1  christos {
    291  1.1  christos 	const struct cert_tbl *q = b;
    292  1.1  christos 
    293  1.1  christos 	return memcmp(a, &q->guid, sizeof(q->guid));
    294  1.1  christos }
    295  1.1  christos 
    296  1.1  christos static struct cert_tbl *
    297  1.1  christos get_cert_info(uuid_t *uuid)
    298  1.1  christos {
    299  1.1  christos 	static bool init_done = false;
    300  1.1  christos 	static struct cert_tbl tbl[] = {
    301  1.1  christos #define _X(c,f,s)	{ .guid = EFI_CERT_ ## c ## _GUID, .name = #c, \
    302  1.1  christos  			  .sigfn = f, .sigsz = s, },
    303  1.1  christos 		EFI_CERT_GUIDS
    304  1.1  christos #undef _X
    305  1.1  christos 	};
    306  1.1  christos 	struct cert_tbl *tp;
    307  1.1  christos 
    308  1.1  christos 	if (!init_done) {
    309  1.1  christos 		qsort(tbl, __arraycount(tbl), sizeof(*tbl), sortcmpfn);
    310  1.1  christos 		init_done = true;
    311  1.1  christos 	}
    312  1.1  christos 
    313  1.1  christos 	tp = bsearch(uuid, tbl, __arraycount(tbl), sizeof(*tbl), srchcmpfn);
    314  1.1  christos 	if (tp == NULL) {
    315  1.1  christos 		printf("unknown owner GUID: ");
    316  1.1  christos 		uuid_printf(uuid);
    317  1.1  christos 		printf("\n");
    318  1.1  christos 	}
    319  1.1  christos 	return tp;
    320  1.1  christos }
    321  1.1  christos 
    322  1.1  christos /************************************************************************/
    323  1.1  christos 
    324  1.1  christos static inline const char *
    325  1.1  christos cert_info_name(struct cert_tbl *tp)
    326  1.1  christos {
    327  1.1  christos 
    328  1.1  christos 	return tp ? tp->name : EFI_CERT_GUID_UNKNOWN;
    329  1.1  christos }
    330  1.1  christos 
    331  1.1  christos PUBLIC const char *
    332  1.1  christos get_cert_name(uuid_t *uuid)
    333  1.1  christos {
    334  1.1  christos 
    335  1.1  christos 	return cert_info_name(get_cert_info(uuid));
    336  1.1  christos }
    337  1.1  christos 
    338  1.1  christos static struct cert_tbl *
    339  1.1  christos show_signature_list_header(EFI_SIGNATURE_LIST_t *lp, int indent)
    340  1.1  christos {
    341  1.1  christos 	struct cert_tbl *tp;
    342  1.1  christos 	const char *name;
    343  1.1  christos 
    344  1.1  christos 	tp = get_cert_info(&lp->SignatureType);
    345  1.1  christos 	name = cert_info_name(tp);
    346  1.1  christos 	printf("%*sSigType: %s\n", indent, "", name);
    347  1.1  christos 	printf("%*sListSize: %d (0x%x)\n", indent, "",
    348  1.1  christos 	    lp->SignatureListSize, lp->SignatureListSize);
    349  1.1  christos 	printf("%*sHdrSize: %d (0x%x)\n", indent, "",
    350  1.1  christos 	    lp->SignatureHeaderSize, lp->SignatureHeaderSize);
    351  1.1  christos 	printf("%*sSigSize: %d (0x%x)\n", indent, "",
    352  1.1  christos 	    lp->SignatureSize, lp->SignatureSize);
    353  1.4  riastrad 
    354  1.1  christos 	return tp;
    355  1.4  riastrad }
    356  1.1  christos 
    357  1.1  christos static int
    358  1.1  christos parse_signature_list(const uint8_t *bp, size_t sz, int indent)
    359  1.1  christos {
    360  1.1  christos 	union {
    361  1.1  christos 		const uint8_t *bp;
    362  1.1  christos 		EFI_SIGNATURE_LIST_t *lp;
    363  1.1  christos 	} u;
    364  1.1  christos 	struct cert_tbl *tp;
    365  1.1  christos 	const uint8_t *endall, *endlist;
    366  1.1  christos 
    367  1.1  christos 	u.bp = bp;
    368  1.1  christos 	endall = bp + sz;
    369  1.1  christos 	while (u.bp < endall) {
    370  1.1  christos 		tp = show_signature_list_header(u.lp, indent);
    371  1.1  christos 
    372  1.1  christos 		/*
    373  1.1  christos 		 * XXX: all the documented cases seem to have no
    374  1.1  christos 		 * signature header.
    375  1.1  christos 		 */
    376  1.1  christos 		if (u.lp->SignatureHeaderSize != 0) {
    377  1.1  christos 			printf("expected zero SignatureHeaderSize: got %d\n",
    378  1.1  christos 			    u.lp->SignatureHeaderSize);
    379  1.1  christos 		}
    380  1.1  christos 		assert(u.lp->SignatureHeaderSize == 0);
    381  1.1  christos 
    382  1.1  christos 		/*
    383  1.1  christos 		 * Sanity check.
    384  1.1  christos 		 */
    385  1.1  christos 		if (tp && tp->sigsz && tp->sigsz != u.lp->SignatureSize) {
    386  1.1  christos 			printf("expected signature size: %zu, got: %u\n",
    387  1.1  christos 			    tp->sigsz, u.lp->SignatureSize);
    388  1.1  christos 		}
    389  1.1  christos 
    390  1.1  christos 		endlist = u.bp + u.lp->SignatureListSize;
    391  1.1  christos 		for (uint8_t *sp = u.lp->SignatureListBody
    392  1.1  christos 			 + u.lp->SignatureHeaderSize;
    393  1.1  christos 		     sp < endlist;
    394  1.1  christos 		     sp += u.lp->SignatureSize) {
    395  1.1  christos 			if (tp)
    396  1.1  christos 				tp->sigfn(sp, u.lp->SignatureSize, 2);
    397  1.1  christos 			else
    398  1.1  christos 				sigfn0(sp, u.lp->SignatureSize, 2);
    399  1.1  christos 		}
    400  1.1  christos 
    401  1.1  christos 		u.bp = endlist;
    402  1.1  christos 	}
    403  1.1  christos 	return 0;
    404  1.1  christos }
    405  1.1  christos 
    406  1.1  christos PUBLIC int
    407  1.1  christos show_cert_data(efi_var_t *v, bool dbg)
    408  1.1  christos {
    409  1.1  christos 	union {
    410  1.1  christos 		const uint8_t *bp;
    411  1.1  christos 		EFI_SIGNATURE_LIST_t *lp;
    412  1.1  christos 	} u;
    413  1.1  christos 	const uint8_t *end;
    414  1.1  christos 	const char *name;
    415  1.1  christos 
    416  1.1  christos 	printf("%s: ", v->name);
    417  1.1  christos 
    418  1.1  christos 	u.bp = v->ev.data;
    419  1.1  christos 	end = u.bp + v->ev.datasize;
    420  1.1  christos 	for (;;) {
    421  1.1  christos 		name = get_cert_name(&u.lp->SignatureType);
    422  1.1  christos 
    423  1.1  christos 		u.bp += u.lp->SignatureListSize;
    424  1.1  christos 		if (u.bp < end)
    425  1.1  christos 			printf("%s ", name);
    426  1.1  christos 		else {
    427  1.1  christos 			printf("%s\n", name);
    428  1.1  christos 			break;
    429  1.1  christos 		}
    430  1.1  christos 	}
    431  1.1  christos 
    432  1.1  christos 	if (dbg)
    433  1.1  christos 		parse_signature_list(v->ev.data, v->ev.datasize, 2);
    434  1.1  christos 
    435  1.1  christos 	return 0;
    436  1.1  christos }
    437