1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #define ELF_TARGET_ALL /* get definitions of all section flags */ 27 28 #include <sys/types.h> 29 #include <sys/stat.h> 30 #include <fcntl.h> 31 #include <unistd.h> 32 #include <strings.h> 33 #include <stddef.h> 34 #include <stdlib.h> 35 #include <libintl.h> 36 #include <dirent.h> 37 #include <errno.h> 38 #include <libelf.h> 39 #include <gelf.h> 40 #include <cryptoutil.h> 41 #include <sha1.h> 42 #include <sys/crypto/elfsign.h> 43 #include <libelfsign.h> 44 45 #ifndef SHA1_DIGEST_LENGTH 46 #define SHA1_DIGEST_LENGTH 20 47 #endif /* SHA1_DIGEST_LENGTH */ 48 49 const char SUNW_ELF_SIGNATURE_ID[] = ELF_SIGNATURE_SECTION; 50 const char OID_sha1WithRSAEncryption[] = "1.2.840.113549.1.1.5"; 51 52 static ELFsign_status_t elfsign_adjustoffsets(ELFsign_t ess, 53 Elf_Scn *scn, uint64_t new_size); 54 static uint32_t elfsign_switch_uint32(uint32_t i); 55 static ELFsign_status_t elfsign_switch(ELFsign_t ess, 56 struct filesignatures *fssp, enum ES_ACTION action); 57 58 struct filesig_extraction { 59 filesig_vers_t fsx_version; 60 char *fsx_format; 61 char fsx_signer_DN[ELFCERT_MAX_DN_LEN]; 62 size_t fsx_signer_DN_len; 63 uchar_t fsx_signature[SIG_MAX_LENGTH]; 64 size_t fsx_sig_len; 65 char fsx_sig_oid[100]; 66 size_t fsx_sig_oid_len; 67 time_t fsx_time; 68 }; 69 70 static char * 71 version_to_str(filesig_vers_t v) 72 { 73 char *ret; 74 75 switch (v) { 76 case FILESIG_VERSION1: 77 ret = "VERSION1"; 78 break; 79 case FILESIG_VERSION2: 80 ret = "VERSION2"; 81 break; 82 case FILESIG_VERSION3: 83 ret = "VERSION3"; 84 break; 85 case FILESIG_VERSION4: 86 ret = "VERSION4"; 87 break; 88 default: 89 ret = "UNKNOWN"; 90 break; 91 } 92 return (ret); 93 } 94 95 /* 96 * Update filesignatures to include the v1/v2 filesig, 97 * composed of signer DN, signature, and OID. 98 */ 99 static struct filesignatures * 100 filesig_insert_dso(struct filesignatures *fssp, 101 filesig_vers_t version, 102 const char *dn, 103 int dn_len, 104 const uchar_t *sig, 105 int sig_len, 106 const char *oid, 107 int oid_len) 108 { 109 struct filesig *fsgp; 110 char *fsdatap; 111 112 if (oid == NULL) { 113 /* 114 * This OID is used for the rsa_md5_sha1 format signature also. 115 * This use is historical, and is hence continued, 116 * despite its lack of technical accuracy. 117 */ 118 oid = OID_sha1WithRSAEncryption; 119 oid_len = strlen(oid); 120 } 121 122 /* 123 * for now, always insert a single-signature signature block 124 */ 125 if (fssp != NULL) 126 free(fssp); 127 fssp = (struct filesignatures *) 128 malloc(filesig_ALIGN(sizeof (struct filesignatures) + 129 dn_len + sig_len + oid_len)); 130 if (fssp == NULL) 131 return (fssp); 132 133 fssp->filesig_cnt = 1; 134 fssp->filesig_pad = 0; /* reserve for future use */ 135 136 fsgp = &fssp->filesig_sig; 137 fsgp->filesig_size = sizeof (struct filesig) + 138 dn_len + sig_len + oid_len; 139 fsgp->filesig_version = version; 140 switch (version) { 141 case FILESIG_VERSION1: 142 case FILESIG_VERSION2: 143 fsgp->filesig_size -= sizeof (struct filesig) - 144 offsetof(struct filesig, filesig_v1_data[0]); 145 fsgp->filesig_v1_dnsize = dn_len; 146 fsgp->filesig_v1_sigsize = sig_len; 147 fsgp->filesig_v1_oidsize = oid_len; 148 fsdatap = &fsgp->filesig_v1_data[0]; 149 break; 150 case FILESIG_VERSION3: 151 case FILESIG_VERSION4: 152 fsgp->filesig_size -= sizeof (struct filesig) - 153 offsetof(struct filesig, filesig_v3_data[0]); 154 fsgp->filesig_v3_time = time(NULL); 155 fsgp->filesig_v3_dnsize = dn_len; 156 fsgp->filesig_v3_sigsize = sig_len; 157 fsgp->filesig_v3_oidsize = oid_len; 158 fsdatap = &fsgp->filesig_v3_data[0]; 159 break; 160 default: 161 cryptodebug("filesig_insert_dso: unknown version: %d", 162 version); 163 free(fssp); 164 return (NULL); 165 } 166 (void) memcpy(fsdatap, dn, dn_len); 167 fsdatap += dn_len; 168 (void) memcpy(fsdatap, (char *)sig, sig_len); 169 fsdatap += sig_len; 170 (void) memcpy(fsdatap, oid, oid_len); 171 fsdatap += oid_len; 172 fsgp = filesig_next(fsgp); 173 (void) memset(fsdatap, 0, (char *)(fsgp) - fsdatap); 174 175 return (fssp); 176 } 177 178 /* 179 * filesig_extract - extract filesig structure to internal form 180 */ 181 static filesig_vers_t 182 filesig_extract(struct filesig *fsgp, struct filesig_extraction *fsxp) 183 { 184 char *fsdp; 185 186 #define filesig_extract_common(cp, field, data_var, len_var, len_limit) { \ 187 len_var = len_limit; \ 188 if (len_var > fsgp->field) \ 189 len_var = fsgp->field; \ 190 (void) memcpy(data_var, cp, len_var); \ 191 cp += fsgp->field; } 192 #define filesig_extract_str(cp, field, data_var, len_var) \ 193 filesig_extract_common(cp, field, data_var, len_var, \ 194 sizeof (data_var) - 1); \ 195 data_var[len_var] = '\0'; 196 #define filesig_extract_opaque(cp, field, data_var, len_var) \ 197 filesig_extract_common(cp, field, data_var, len_var, sizeof (data_var)) 198 199 fsxp->fsx_version = fsgp->filesig_version; 200 cryptodebug("filesig_extract: version=%s", 201 version_to_str(fsxp->fsx_version)); 202 switch (fsxp->fsx_version) { 203 case FILESIG_VERSION1: 204 case FILESIG_VERSION2: 205 /* 206 * extract VERSION1 DN, signature, and OID 207 */ 208 fsdp = fsgp->filesig_v1_data; 209 fsxp->fsx_format = ES_FMT_RSA_MD5_SHA1; 210 fsxp->fsx_time = 0; 211 filesig_extract_str(fsdp, filesig_v1_dnsize, 212 fsxp->fsx_signer_DN, fsxp->fsx_signer_DN_len); 213 filesig_extract_opaque(fsdp, filesig_v1_sigsize, 214 fsxp->fsx_signature, fsxp->fsx_sig_len); 215 filesig_extract_str(fsdp, filesig_v1_oidsize, 216 fsxp->fsx_sig_oid, fsxp->fsx_sig_oid_len); 217 break; 218 case FILESIG_VERSION3: 219 case FILESIG_VERSION4: 220 fsdp = fsgp->filesig_v3_data; 221 fsxp->fsx_format = ES_FMT_RSA_SHA1; 222 fsxp->fsx_time = fsgp->filesig_v3_time; 223 filesig_extract_str(fsdp, filesig_v3_dnsize, 224 fsxp->fsx_signer_DN, fsxp->fsx_signer_DN_len); 225 filesig_extract_opaque(fsdp, filesig_v3_sigsize, 226 fsxp->fsx_signature, fsxp->fsx_sig_len); 227 filesig_extract_str(fsdp, filesig_v3_oidsize, 228 fsxp->fsx_sig_oid, fsxp->fsx_sig_oid_len); 229 break; 230 default: 231 break; 232 } 233 234 return (fsxp->fsx_version); 235 } 236 237 ELFsign_status_t 238 elfsign_begin(const char *filename, enum ES_ACTION action, ELFsign_t *essp) 239 { 240 Elf_Cmd elfcmd; 241 int oflags = 0; 242 short l_type; 243 ELFsign_t ess; 244 struct stat stb; 245 union { 246 char c[2]; 247 short s; 248 } uorder; 249 GElf_Ehdr elfehdr; 250 char *ident; 251 252 switch (action) { 253 case ES_GET: 254 case ES_GET_CRYPTO: 255 case ES_GET_FIPS140: 256 cryptodebug("elfsign_begin for get"); 257 elfcmd = ELF_C_READ; 258 oflags = O_RDONLY | O_NOCTTY | O_NDELAY; 259 l_type = F_RDLCK; 260 break; 261 case ES_UPDATE_RSA_MD5_SHA1: 262 case ES_UPDATE_RSA_SHA1: 263 cryptodebug("elfsign_begin for update"); 264 elfcmd = ELF_C_RDWR; 265 oflags = O_RDWR | O_NOCTTY | O_NDELAY; 266 l_type = F_WRLCK; 267 break; 268 default: 269 return (ELFSIGN_UNKNOWN); 270 } 271 272 if ((ess = malloc(sizeof (struct ELFsign_s))) == NULL) { 273 return (ELFSIGN_UNKNOWN); 274 } 275 (void) memset((void *)ess, 0, sizeof (struct ELFsign_s)); 276 277 if (!elfcertlib_init(ess)) { 278 cryptodebug("elfsign_begin: failed initialization"); 279 return (ELFSIGN_UNKNOWN); 280 } 281 282 ess->es_elf = NULL; 283 ess->es_action = action; 284 ess->es_version = FILESIG_UNKNOWN; 285 ess->es_pathname = NULL; 286 ess->es_certpath = NULL; 287 288 if (filename == NULL) { 289 *essp = ess; 290 return (ELFSIGN_SUCCESS); 291 } 292 293 if ((ess->es_fd = open(filename, oflags)) == -1) { 294 elfsign_end(ess); 295 return (ELFSIGN_INVALID_ELFOBJ); 296 } 297 if ((fstat(ess->es_fd, &stb) == -1) || !S_ISREG(stb.st_mode)) { 298 elfsign_end(ess); 299 return (ELFSIGN_INVALID_ELFOBJ); 300 } 301 if ((ess->es_pathname = strdup(filename)) == NULL) { 302 elfsign_end(ess); 303 return (ELFSIGN_UNKNOWN); 304 } 305 /* 306 * The following lock is released in elfsign_end() when we close(2) 307 * the es_fd. This ensures that we aren't trying verify a file 308 * we are currently updating. 309 */ 310 ess->es_flock.l_type = l_type; 311 ess->es_flock.l_whence = SEEK_CUR; 312 ess->es_flock.l_start = 0; 313 ess->es_flock.l_len = 0; 314 if (fcntl(ess->es_fd, F_SETLK, &ess->es_flock) == -1) { 315 cryptodebug("fcntl(F_SETLK) of %s failed with: %s", 316 ess->es_pathname, strerror(errno)); 317 elfsign_end(ess); 318 return (ELFSIGN_UNKNOWN); 319 } 320 321 if (elf_version(EV_CURRENT) == EV_NONE) { 322 elfsign_end(ess); 323 return (ELFSIGN_UNKNOWN); 324 } 325 326 if ((ess->es_elf = elf_begin(ess->es_fd, elfcmd, 327 (Elf *)NULL)) == NULL) { 328 cryptodebug("elf_begin() failed: %s", elf_errmsg(-1)); 329 elfsign_end(ess); 330 return (ELFSIGN_INVALID_ELFOBJ); 331 } 332 333 if (gelf_getehdr(ess->es_elf, &elfehdr) == NULL) { 334 cryptodebug("elf_getehdr() failed: %s", elf_errmsg(-1)); 335 elfsign_end(ess); 336 return (ELFSIGN_INVALID_ELFOBJ); 337 } 338 ess->es_has_phdr = (elfehdr.e_phnum != 0); 339 340 uorder.s = ELFDATA2MSB << 8 | ELFDATA2LSB; 341 ident = elf_getident(ess->es_elf, NULL); 342 if (ident == NULL) { 343 cryptodebug("elf_getident() failed: %s", elf_errmsg(-1)); 344 elfsign_end(ess); 345 return (ELFSIGN_INVALID_ELFOBJ); 346 } 347 ess->es_same_endian = (ident[EI_DATA] == uorder.c[0]); 348 ess->es_ei_class = ident[EI_CLASS]; 349 350 /* 351 * Call elf_getshstrndx to be sure we have a real ELF object 352 * this is required because elf_begin doesn't check that. 353 */ 354 if (elf_getshstrndx(ess->es_elf, &ess->es_shstrndx) == 0) { 355 elfsign_end(ess); 356 cryptodebug("elfsign_begin: elf_getshstrndx failed"); 357 return (ELFSIGN_INVALID_ELFOBJ); 358 } 359 360 /* 361 * Make sure libelf doesn't rearrange section ordering / offsets. 362 */ 363 (void) elf_flagelf(ess->es_elf, ELF_C_SET, ELF_F_LAYOUT); 364 365 *essp = ess; 366 367 return (ELFSIGN_SUCCESS); 368 } 369 370 /* 371 * elfsign_end - cleanup the ELFsign_t 372 * 373 * IN/OUT: ess 374 */ 375 void 376 elfsign_end(ELFsign_t ess) 377 { 378 if (ess == NULL) 379 return; 380 381 if (ess->es_elf != NULL && ES_ACTISUPDATE(ess->es_action)) { 382 if (elf_update(ess->es_elf, ELF_C_WRITE) == -1) { 383 cryptodebug("elf_update() failed: %s", 384 elf_errmsg(-1)); 385 return; 386 } 387 } 388 389 if (ess->es_fd != -1) { 390 (void) close(ess->es_fd); 391 ess->es_fd = -1; 392 } 393 394 if (ess->es_pathname != NULL) { 395 free(ess->es_pathname); 396 ess->es_pathname = NULL; 397 } 398 if (ess->es_certpath != NULL) { 399 free(ess->es_certpath); 400 ess->es_certpath = NULL; 401 } 402 403 if (ess->es_elf != NULL) { 404 (void) elf_end(ess->es_elf); 405 ess->es_elf = NULL; 406 } 407 408 elfcertlib_fini(ess); 409 410 free(ess); 411 } 412 413 /* 414 * set the certificate path 415 */ 416 ELFsign_status_t 417 elfsign_setcertpath(ELFsign_t ess, const char *certpath) 418 { 419 /* 420 * Normally use of access(2) is insecure, here we are only 421 * doing it to help provide early failure and better error 422 * checking, so there is no race condition. 423 */ 424 if (access(certpath, R_OK) != 0) 425 return (ELFSIGN_INVALID_CERTPATH); 426 427 if ((ess->es_certpath = strdup(certpath)) == NULL) 428 return (ELFSIGN_FAILED); 429 430 if (ES_ACTISUPDATE(ess->es_action)) { 431 ELFCert_t cert = NULL; 432 char *subject; 433 434 /* set the version based on the certificate */ 435 if (elfcertlib_getcert(ess, ess->es_certpath, NULL, 436 &cert, ess->es_action)) { 437 if ((subject = elfcertlib_getdn(cert)) != NULL) { 438 if (strstr(subject, ELFSIGN_CRYPTO)) 439 ess->es_version = (ess->es_action == 440 ES_UPDATE_RSA_MD5_SHA1) ? 441 FILESIG_VERSION1 : FILESIG_VERSION3; 442 else 443 ess->es_version = (ess->es_action == 444 ES_UPDATE_RSA_MD5_SHA1) ? 445 FILESIG_VERSION2 : FILESIG_VERSION4; 446 } 447 elfcertlib_releasecert(ess, cert); 448 } 449 if (ess->es_version == FILESIG_UNKNOWN) 450 return (ELFSIGN_FAILED); 451 } 452 return (ELFSIGN_SUCCESS); 453 } 454 455 /* 456 * set the callback context 457 */ 458 void 459 elfsign_setcallbackctx(ELFsign_t ess, void *ctx) 460 { 461 ess->es_callbackctx = ctx; 462 } 463 464 /* 465 * set the signature extraction callback 466 */ 467 void 468 elfsign_setsigvercallback(ELFsign_t ess, 469 void (*cb)(void *, void *, size_t, ELFCert_t)) 470 { 471 ess->es_sigvercallback = cb; 472 } 473 474 /* 475 * elfsign_signatures 476 * 477 * IN: ess, fsspp, action 478 * OUT: fsspp 479 */ 480 ELFsign_status_t 481 elfsign_signatures(ELFsign_t ess, 482 struct filesignatures **fsspp, 483 size_t *fslen, 484 enum ES_ACTION action) 485 { 486 Elf_Scn *scn = NULL, *sig_scn = NULL; 487 GElf_Shdr shdr; 488 Elf_Data *data = NULL; 489 const char *elf_section = SUNW_ELF_SIGNATURE_ID; 490 int fscnt, fssize; 491 struct filesig *fsgp, *fsgpnext; 492 uint64_t sig_offset = 0; 493 494 cryptodebug("elfsign_signature"); 495 if ((ess == NULL) || (fsspp == NULL)) { 496 cryptodebug("invalid arguments"); 497 return (ELFSIGN_UNKNOWN); 498 } 499 500 cryptodebug("elfsign_signature %s for %s", 501 ES_ACTISUPDATE(action) ? "ES_UPDATE" : "ES_GET", elf_section); 502 503 (void) elf_errno(); 504 while ((scn = elf_nextscn(ess->es_elf, scn)) != NULL) { 505 const char *sh_name; 506 /* 507 * Do a string compare to examine each section header 508 * to see if this is the section that needs to be updated. 509 */ 510 if (gelf_getshdr(scn, &shdr) == NULL) { 511 cryptodebug("gelf_getshdr() failed: %s", 512 elf_errmsg(-1)); 513 return (ELFSIGN_FAILED); 514 } 515 sh_name = elf_strptr(ess->es_elf, ess->es_shstrndx, 516 (size_t)shdr.sh_name); 517 if (strcmp(sh_name, elf_section) == 0) { 518 cryptodebug("elfsign_signature: found %s", elf_section); 519 sig_scn = scn; 520 break; 521 } 522 if (shdr.sh_type != SHT_NOBITS && 523 sig_offset < shdr.sh_offset + shdr.sh_size) { 524 sig_offset = shdr.sh_offset + shdr.sh_size; 525 } 526 } 527 if (elf_errmsg(0) != NULL) { 528 cryptodebug("unexpected error: %s", elf_section, 529 elf_errmsg(-1)); 530 return (ELFSIGN_FAILED); 531 } 532 533 if (ES_ACTISUPDATE(action) && (sig_scn == NULL)) { 534 size_t old_size, new_size; 535 char *new_d_buf; 536 537 cryptodebug("elfsign_signature: %s not found - creating", 538 elf_section); 539 540 /* 541 * insert section name in .shstrtab 542 */ 543 if ((scn = elf_getscn(ess->es_elf, ess->es_shstrndx)) == 0) { 544 cryptodebug("elf_getscn() failed: %s", 545 elf_errmsg(-1)); 546 return (ELFSIGN_FAILED); 547 } 548 if (gelf_getshdr(scn, &shdr) == NULL) { 549 cryptodebug("gelf_getshdr() failed: %s", 550 elf_errmsg(-1)); 551 return (ELFSIGN_FAILED); 552 } 553 if ((data = elf_getdata(scn, data)) == NULL) { 554 cryptodebug("elf_getdata() failed: %s", 555 elf_errmsg(-1)); 556 return (ELFSIGN_FAILED); 557 } 558 old_size = data->d_size; 559 if (old_size != shdr.sh_size) { 560 cryptodebug("mismatch between data size %d " 561 "and section size %lld", old_size, shdr.sh_size); 562 return (ELFSIGN_FAILED); 563 } 564 new_size = old_size + strlen(elf_section) + 1; 565 if ((new_d_buf = malloc(new_size)) == NULL) 566 return (ELFSIGN_FAILED); 567 568 (void) memcpy(new_d_buf, data->d_buf, old_size); 569 (void) strlcpy(new_d_buf + old_size, elf_section, 570 new_size - old_size); 571 data->d_buf = new_d_buf; 572 data->d_size = new_size; 573 data->d_align = 1; 574 /* 575 * Add the section name passed in to the end of the file. 576 * Initialize the fields in the Section Header that 577 * libelf will not fill in. 578 */ 579 if ((sig_scn = elf_newscn(ess->es_elf)) == 0) { 580 cryptodebug("elf_newscn() failed: %s", 581 elf_errmsg(-1)); 582 return (ELFSIGN_FAILED); 583 } 584 if (gelf_getshdr(sig_scn, &shdr) == 0) { 585 cryptodebug("gelf_getshdr() failed: %s", 586 elf_errmsg(-1)); 587 return (ELFSIGN_FAILED); 588 } 589 shdr.sh_name = old_size; 590 shdr.sh_type = SHT_SUNW_SIGNATURE; 591 shdr.sh_flags = SHF_EXCLUDE; 592 shdr.sh_addr = 0; 593 shdr.sh_link = 0; 594 shdr.sh_info = 0; 595 shdr.sh_size = 0; 596 shdr.sh_offset = sig_offset; 597 shdr.sh_addralign = 1; 598 599 /* 600 * Flush the changes to the underlying elf32 or elf64 601 * section header. 602 */ 603 if (gelf_update_shdr(sig_scn, &shdr) == 0) { 604 cryptodebug("gelf_update_shdr failed"); 605 return (ELFSIGN_FAILED); 606 } 607 608 if ((data = elf_newdata(sig_scn)) == NULL) { 609 cryptodebug("can't add elf data area for %s: %s", 610 elf_section, elf_errmsg(-1)); 611 return (ELFSIGN_FAILED); 612 } 613 if (elfsign_adjustoffsets(ess, scn, 614 old_size + strlen(elf_section) + 1) != ELFSIGN_SUCCESS) { 615 cryptodebug("can't adjust for new section name %s", 616 elf_section); 617 return (ELFSIGN_FAILED); 618 } 619 } else { 620 if (sig_scn == NULL) { 621 cryptodebug("can't find signature section"); 622 *fsspp = NULL; 623 return (ELFSIGN_NOTSIGNED); 624 } 625 if ((data = elf_getdata(sig_scn, NULL)) == 0) { 626 cryptodebug("can't get section data for %s", 627 elf_section); 628 return (ELFSIGN_FAILED); 629 } 630 } 631 632 if (ES_ACTISUPDATE(action)) { 633 fssize = offsetof(struct filesignatures, _u1); 634 if (*fsspp != NULL) { 635 fsgp = &(*fsspp)->filesig_sig; 636 for (fscnt = 0; fscnt < (*fsspp)->filesig_cnt; 637 fscnt++) { 638 fsgpnext = filesig_next(fsgp); 639 fssize += (char *)(fsgpnext) - (char *)(fsgp); 640 fsgp = fsgpnext; 641 } 642 } 643 if (shdr.sh_addr != 0) { 644 cryptodebug("section %s is part of a loadable segment, " 645 "it cannot be changed.\n", elf_section); 646 return (ELFSIGN_FAILED); 647 } 648 if ((data->d_buf = malloc(fssize)) == NULL) 649 return (ELFSIGN_FAILED); 650 if (*fsspp != NULL) { 651 (void) memcpy(data->d_buf, *fsspp, fssize); 652 (void) elfsign_switch(ess, 653 (struct filesignatures *)data->d_buf, action); 654 } 655 data->d_size = fssize; 656 data->d_align = 1; 657 data->d_type = ELF_T_BYTE; 658 cryptodebug("elfsign_signature: data->d_size = %d", 659 data->d_size); 660 if (elfsign_adjustoffsets(ess, sig_scn, fssize) != 661 ELFSIGN_SUCCESS) { 662 cryptodebug("can't adjust for revised signature " 663 "section contents"); 664 return (ELFSIGN_FAILED); 665 } 666 } else { 667 *fsspp = malloc(data->d_size); 668 if (*fsspp == NULL) 669 return (ELFSIGN_FAILED); 670 (void) memcpy(*fsspp, data->d_buf, data->d_size); 671 if (elfsign_switch(ess, *fsspp, ES_GET) != ELFSIGN_SUCCESS) { 672 free(*fsspp); 673 *fsspp = NULL; 674 return (ELFSIGN_FAILED); 675 } 676 *fslen = data->d_size; 677 } 678 679 return (ELFSIGN_SUCCESS); 680 } 681 682 static ELFsign_status_t 683 elfsign_adjustoffsets(ELFsign_t ess, Elf_Scn *scn, uint64_t new_size) 684 { 685 GElf_Ehdr elfehdr; 686 GElf_Shdr shdr; 687 uint64_t prev_end, scn_offset; 688 char *name; 689 Elf_Scn *scnp; 690 Elf_Data *data; 691 ELFsign_status_t retval = ELFSIGN_FAILED; 692 struct scninfo { 693 struct scninfo *scni_next; 694 Elf_Scn *scni_scn; 695 uint64_t scni_offset; 696 } *scnip = NULL, *tmpscnip, **scnipp; 697 698 /* get the size of the current section */ 699 if (gelf_getshdr(scn, &shdr) == NULL) 700 return (ELFSIGN_FAILED); 701 if (shdr.sh_size == new_size) 702 return (ELFSIGN_SUCCESS); 703 scn_offset = shdr.sh_offset; 704 name = elf_strptr(ess->es_elf, ess->es_shstrndx, 705 (size_t)shdr.sh_name); 706 if (shdr.sh_flags & SHF_ALLOC && ess->es_has_phdr) { 707 cryptodebug("elfsign_adjustoffsets: " 708 "can't move allocated section %s", name ? name : "NULL"); 709 return (ELFSIGN_FAILED); 710 } 711 712 /* resize the desired section */ 713 cryptodebug("elfsign_adjustoffsets: " 714 "resizing %s at 0x%llx from 0x%llx to 0x%llx", 715 name ? name : "NULL", shdr.sh_offset, shdr.sh_size, new_size); 716 shdr.sh_size = new_size; 717 if (gelf_update_shdr(scn, &shdr) == 0) { 718 cryptodebug("gelf_update_shdr failed"); 719 goto bad; 720 } 721 prev_end = shdr.sh_offset + shdr.sh_size; 722 723 /* 724 * find sections whose data follows the changed section 725 * must scan all sections since section data may not 726 * be in same order as section headers 727 */ 728 scnp = elf_getscn(ess->es_elf, 0); /* "seek" to start */ 729 while ((scnp = elf_nextscn(ess->es_elf, scnp)) != NULL) { 730 if (gelf_getshdr(scnp, &shdr) == NULL) 731 goto bad; 732 if (shdr.sh_offset <= scn_offset) 733 continue; 734 name = elf_strptr(ess->es_elf, ess->es_shstrndx, 735 (size_t)shdr.sh_name); 736 if (shdr.sh_flags & SHF_ALLOC && ess->es_has_phdr) { 737 if (shdr.sh_type == SHT_NOBITS) { 738 /* .bss can occasionally overlap .shrtab */ 739 continue; 740 } 741 cryptodebug("elfsign_adjustoffsets: " 742 "can't move allocated section %s", 743 name ? name : "NULL"); 744 goto bad; 745 } 746 /* 747 * force reading of data to memory image 748 */ 749 data = NULL; 750 while ((data = elf_rawdata(scnp, data)) != NULL) 751 ; 752 /* 753 * capture section information 754 * insert into list in order of sh_offset 755 */ 756 cryptodebug("elfsign_adjustoffsets: " 757 "may have to adjust section %s, offset 0x%llx", 758 name ? name : "NULL", shdr.sh_offset); 759 tmpscnip = (struct scninfo *)malloc(sizeof (struct scninfo)); 760 if (tmpscnip == NULL) { 761 cryptodebug("elfsign_adjustoffsets: " 762 "memory allocation failure"); 763 goto bad; 764 } 765 tmpscnip->scni_scn = scnp; 766 tmpscnip->scni_offset = shdr.sh_offset; 767 for (scnipp = &scnip; *scnipp != NULL; 768 scnipp = &(*scnipp)->scni_next) { 769 if ((*scnipp)->scni_offset > tmpscnip->scni_offset) 770 break; 771 } 772 tmpscnip->scni_next = *scnipp; 773 *scnipp = tmpscnip; 774 } 775 776 /* move following sections as necessary */ 777 for (tmpscnip = scnip; tmpscnip != NULL; 778 tmpscnip = tmpscnip->scni_next) { 779 scnp = tmpscnip->scni_scn; 780 if (gelf_getshdr(scnp, &shdr) == NULL) { 781 cryptodebug("elfsign_adjustoffsets: " 782 "elf_getshdr for section %d failed", 783 elf_ndxscn(scnp)); 784 goto bad; 785 } 786 if (shdr.sh_offset >= prev_end) 787 break; 788 prev_end = (prev_end + shdr.sh_addralign - 1) & 789 (-shdr.sh_addralign); 790 name = elf_strptr(ess->es_elf, ess->es_shstrndx, 791 (size_t)shdr.sh_name); 792 cryptodebug("elfsign_adjustoffsets: " 793 "moving %s size 0x%llx from 0x%llx to 0x%llx", 794 name ? name : "NULL", shdr.sh_size, 795 shdr.sh_offset, prev_end); 796 shdr.sh_offset = prev_end; 797 if (gelf_update_shdr(scnp, &shdr) == 0) { 798 cryptodebug("gelf_update_shdr failed"); 799 goto bad; 800 } 801 prev_end = shdr.sh_offset + shdr.sh_size; 802 } 803 804 /* 805 * adjust section header offset in elf header 806 */ 807 if (gelf_getehdr(ess->es_elf, &elfehdr) == NULL) { 808 cryptodebug("elf_getehdr() failed: %s", elf_errmsg(-1)); 809 goto bad; 810 } 811 if (elfehdr.e_shoff < prev_end) { 812 if (ess->es_ei_class == ELFCLASS32) 813 prev_end = (prev_end + ELF32_FSZ_OFF - 1) & 814 (-ELF32_FSZ_OFF); 815 else if (ess->es_ei_class == ELFCLASS64) 816 prev_end = (prev_end + ELF64_FSZ_OFF - 1) & 817 (-ELF64_FSZ_OFF); 818 cryptodebug("elfsign_adjustoffsets: " 819 "move sh_off from 0x%llx to 0x%llx", 820 elfehdr.e_shoff, prev_end); 821 elfehdr.e_shoff = prev_end; 822 if (gelf_update_ehdr(ess->es_elf, &elfehdr) == 0) { 823 cryptodebug("elf_update_ehdr() failed: %s", 824 elf_errmsg(-1)); 825 goto bad; 826 } 827 } 828 829 retval = ELFSIGN_SUCCESS; 830 831 bad: 832 while (scnip != NULL) { 833 tmpscnip = scnip->scni_next; 834 free(scnip); 835 scnip = tmpscnip; 836 } 837 return (retval); 838 } 839 840 struct filesignatures * 841 elfsign_insert_dso(ELFsign_t ess, 842 struct filesignatures *fssp, 843 const char *dn, 844 int dn_len, 845 const uchar_t *sig, 846 int sig_len, 847 const char *oid, 848 int oid_len) 849 { 850 return (filesig_insert_dso(fssp, ess->es_version, dn, dn_len, 851 sig, sig_len, oid, oid_len)); 852 } 853 854 /*ARGSUSED*/ 855 filesig_vers_t 856 elfsign_extract_sig(ELFsign_t ess, 857 struct filesignatures *fssp, 858 uchar_t *sig, 859 size_t *sig_len) 860 { 861 struct filesig_extraction fsx; 862 filesig_vers_t version; 863 864 if (fssp == NULL) 865 return (FILESIG_UNKNOWN); 866 if (fssp->filesig_cnt != 1) 867 return (FILESIG_UNKNOWN); 868 version = filesig_extract(&fssp->filesig_sig, &fsx); 869 switch (version) { 870 case FILESIG_VERSION1: 871 case FILESIG_VERSION2: 872 case FILESIG_VERSION3: 873 case FILESIG_VERSION4: 874 if (*sig_len >= fsx.fsx_sig_len) { 875 (void) memcpy((char *)sig, (char *)fsx.fsx_signature, 876 *sig_len); 877 *sig_len = fsx.fsx_sig_len; 878 } else 879 version = FILESIG_UNKNOWN; 880 break; 881 default: 882 version = FILESIG_UNKNOWN; 883 break; 884 } 885 886 if (ess->es_version == FILESIG_UNKNOWN) { 887 ess->es_version = version; 888 } 889 890 return (version); 891 } 892 893 static ELFsign_status_t 894 elfsign_hash_common(ELFsign_t ess, uchar_t *hash, size_t *hash_len, 895 boolean_t hash_mem_resident) 896 { 897 Elf_Scn *scn = NULL; 898 ELFsign_status_t elfstat; 899 GElf_Shdr shdr; 900 SHA1_CTX ctx; 901 902 /* The buffer must be large enough to hold the hash */ 903 if (*hash_len < SHA1_DIGEST_LENGTH) 904 return (ELFSIGN_FAILED); 905 906 bzero(hash, *hash_len); 907 908 /* Initialize the digest session */ 909 SHA1Init(&ctx); 910 911 scn = elf_getscn(ess->es_elf, 0); /* "seek" to start */ 912 (void) elf_errno(); 913 while ((scn = elf_nextscn(ess->es_elf, scn)) != 0) { 914 char *name = NULL; 915 Elf_Data *data = NULL; 916 917 if (gelf_getshdr(scn, &shdr) == NULL) { 918 elfstat = ELFSIGN_FAILED; 919 goto done; 920 } 921 922 name = elf_strptr(ess->es_elf, ess->es_shstrndx, 923 (size_t)shdr.sh_name); 924 if (name == NULL) 925 name = "NULL"; 926 927 if (!hash_mem_resident && 928 (ess->es_version == FILESIG_VERSION1 || 929 ess->es_version == FILESIG_VERSION3)) { 930 /* 931 * skip the signature section only 932 */ 933 if (shdr.sh_type == SHT_SUNW_SIGNATURE) { 934 cryptodebug("elfsign_hash: skipping %s", name); 935 continue; 936 } 937 } else if (!(shdr.sh_flags & SHF_ALLOC)) { 938 /* 939 * select only memory resident sections 940 */ 941 cryptodebug("elfsign_hash: skipping %s", name); 942 continue; 943 } 944 945 /* 946 * throw this section into the hash 947 * use elf_rawdata for endian-independence 948 * use elf_getdata to get update of .shstrtab 949 */ 950 while ((data = (shdr.sh_type == SHT_STRTAB ? 951 elf_getdata(scn, data) : elf_rawdata(scn, data))) != NULL) { 952 if (data->d_buf == NULL) { 953 cryptodebug("elfsign_hash: %s has NULL data", 954 name); 955 continue; 956 } 957 cryptodebug("elfsign_hash: updating hash " 958 "with %s data size=%d", name, data->d_size); 959 SHA1Update(&ctx, data->d_buf, data->d_size); 960 } 961 } 962 if (elf_errmsg(0) != NULL) { 963 cryptodebug("elfsign_hash: %s", elf_errmsg(-1)); 964 elfstat = ELFSIGN_FAILED; 965 goto done; 966 } 967 968 SHA1Final(hash, &ctx); 969 *hash_len = SHA1_DIGEST_LENGTH; 970 { /* DEBUG START */ 971 const int hashstr_len = (*hash_len) * 2 + 1; 972 char *hashstr = malloc(hashstr_len); 973 974 if (hashstr != NULL) { 975 tohexstr(hash, *hash_len, hashstr, hashstr_len); 976 cryptodebug("hash value is: %s", hashstr); 977 free(hashstr); 978 } 979 } /* DEBUG END */ 980 elfstat = ELFSIGN_SUCCESS; 981 done: 982 return (elfstat); 983 } 984 985 /* 986 * elfsign_hash - return the hash of the ELF sections affecting execution. 987 * 988 * IN: ess, hash_len 989 * OUT: hash, hash_len 990 */ 991 ELFsign_status_t 992 elfsign_hash(ELFsign_t ess, uchar_t *hash, size_t *hash_len) 993 { 994 return (elfsign_hash_common(ess, hash, hash_len, B_FALSE)); 995 } 996 997 /* 998 * elfsign_hash_mem_resident - return the hash of the ELF sections 999 * with only memory resident sections. 1000 * 1001 * IN: ess, hash_len 1002 * OUT: hash, hash_len 1003 */ 1004 ELFsign_status_t 1005 elfsign_hash_mem_resident(ELFsign_t ess, uchar_t *hash, size_t *hash_len) 1006 { 1007 return (elfsign_hash_common(ess, hash, hash_len, B_TRUE)); 1008 } 1009 1010 1011 /* 1012 * elfsign_verify_signature - Verify the signature of the ELF object. 1013 * 1014 * IN: ess 1015 * OUT: esipp 1016 * RETURNS: 1017 * ELFsign_status_t 1018 */ 1019 ELFsign_status_t 1020 elfsign_verify_signature(ELFsign_t ess, struct ELFsign_sig_info **esipp) 1021 { 1022 ELFsign_status_t ret = ELFSIGN_FAILED; 1023 struct filesignatures *fssp; 1024 struct filesig *fsgp; 1025 size_t fslen; 1026 struct filesig_extraction fsx; 1027 uchar_t hash[SIG_MAX_LENGTH]; 1028 size_t hash_len; 1029 ELFCert_t cert = NULL; 1030 int sigcnt; 1031 int nocert = 0; 1032 struct ELFsign_sig_info *esip = NULL; 1033 1034 if (esipp != NULL) { 1035 esip = (struct ELFsign_sig_info *) 1036 calloc(1, sizeof (struct ELFsign_sig_info)); 1037 *esipp = esip; 1038 } 1039 1040 /* 1041 * Find out which cert we need, based on who signed the ELF object 1042 */ 1043 if (elfsign_signatures(ess, &fssp, &fslen, ES_GET) != ELFSIGN_SUCCESS) { 1044 return (ELFSIGN_NOTSIGNED); 1045 } 1046 1047 if (fssp->filesig_cnt < 1) { 1048 ret = ELFSIGN_FAILED; 1049 goto cleanup; 1050 } 1051 1052 fsgp = &fssp->filesig_sig; 1053 1054 /* 1055 * Scan the signature block, looking for a verifiable signature 1056 */ 1057 for (sigcnt = 0; sigcnt < fssp->filesig_cnt; 1058 sigcnt++, fsgp = filesig_next(fsgp)) { 1059 ess->es_version = filesig_extract(fsgp, &fsx); 1060 cryptodebug("elfsign_verify_signature: version=%s", 1061 version_to_str(ess->es_version)); 1062 switch (ess->es_version) { 1063 case FILESIG_VERSION1: 1064 case FILESIG_VERSION2: 1065 case FILESIG_VERSION3: 1066 case FILESIG_VERSION4: 1067 break; 1068 default: 1069 ret = ELFSIGN_FAILED; 1070 goto cleanup; 1071 } 1072 1073 cryptodebug("elfsign_verify_signature: signer_DN=\"%s\"", 1074 fsx.fsx_signer_DN); 1075 cryptodebug("elfsign_verify_signature: algorithmOID=\"%s\"", 1076 fsx.fsx_sig_oid); 1077 /* return signer DN if requested */ 1078 if (esipp != NULL) { 1079 esip->esi_format = fsx.fsx_format; 1080 if (esip->esi_signer != NULL) 1081 free(esip->esi_signer); 1082 esip->esi_signer = strdup(fsx.fsx_signer_DN); 1083 esip->esi_time = fsx.fsx_time; 1084 } 1085 1086 /* 1087 * look for certificate 1088 */ 1089 if (cert != NULL) 1090 elfcertlib_releasecert(ess, cert); 1091 1092 /* 1093 * skip unfound certificates 1094 */ 1095 if (!elfcertlib_getcert(ess, ess->es_certpath, 1096 fsx.fsx_signer_DN, &cert, ess->es_action)) { 1097 cryptodebug("unable to find certificate " 1098 "with DN=\"%s\" for %s", 1099 fsx.fsx_signer_DN, ess->es_pathname); 1100 nocert++; 1101 continue; 1102 } 1103 1104 /* 1105 * skip unverified certificates 1106 * force verification of crypto certs 1107 */ 1108 if ((ess->es_action == ES_GET_CRYPTO || 1109 ess->es_action == ES_GET_FIPS140 || 1110 strstr(fsx.fsx_signer_DN, ELFSIGN_CRYPTO)) && 1111 !elfcertlib_verifycert(ess, cert)) { 1112 cryptodebug("elfsign_verify_signature: invalid cert"); 1113 nocert++; 1114 continue; 1115 } 1116 1117 /* 1118 * At this time the only sha1WithRSAEncryption is supported, 1119 * so check that is what we have and skip with anything else. 1120 */ 1121 if (strcmp(fsx.fsx_sig_oid, OID_sha1WithRSAEncryption) != 0) { 1122 continue; 1123 } 1124 1125 nocert = 0; 1126 /* 1127 * compute file hash 1128 */ 1129 hash_len = sizeof (hash); 1130 if (elfsign_hash(ess, hash, &hash_len) != ELFSIGN_SUCCESS) { 1131 cryptodebug("elfsign_verify_signature:" 1132 " elfsign_hash failed"); 1133 ret = ELFSIGN_FAILED; 1134 break; 1135 } 1136 1137 { /* DEBUG START */ 1138 const int sigstr_len = fsx.fsx_sig_len * 2 + 1; 1139 char *sigstr = malloc(sigstr_len); 1140 1141 if (sigstr != NULL) { 1142 tohexstr(fsx.fsx_signature, fsx.fsx_sig_len, 1143 sigstr, sigstr_len); 1144 cryptodebug("signature value is: %s", sigstr); 1145 free(sigstr); 1146 } 1147 } /* DEBUG END */ 1148 1149 if (elfcertlib_verifysig(ess, cert, 1150 fsx.fsx_signature, fsx.fsx_sig_len, hash, hash_len)) { 1151 if (ess->es_sigvercallback) 1152 (ess->es_sigvercallback) 1153 (ess->es_callbackctx, fssp, fslen, cert); 1154 /* 1155 * The signature is verified! 1156 */ 1157 ret = ELFSIGN_SUCCESS; 1158 } 1159 1160 cryptodebug("elfsign_verify_signature: invalid signature"); 1161 } 1162 1163 cleanup: 1164 if (cert != NULL) 1165 elfcertlib_releasecert(ess, cert); 1166 1167 free(fssp); 1168 if (ret == ELFSIGN_FAILED && nocert) 1169 ret = ELFSIGN_INVALID_CERTPATH; 1170 return (ret); 1171 } 1172 1173 1174 static uint32_t 1175 elfsign_switch_uint32(uint32_t i) 1176 { 1177 return (((i & 0xff) << 24) | ((i & 0xff00) << 8) | 1178 ((i >> 8) & 0xff00) | ((i >> 24) & 0xff)); 1179 } 1180 1181 static uint64_t 1182 elfsign_switch_uint64(uint64_t i) 1183 { 1184 return (((uint64_t)elfsign_switch_uint32(i) << 32) | 1185 (elfsign_switch_uint32(i >> 32))); 1186 } 1187 1188 /* 1189 * If appropriate, switch the endianness of the filesignatures structure 1190 * Examine the structure only when it is in native endianness 1191 */ 1192 static ELFsign_status_t 1193 elfsign_switch(ELFsign_t ess, struct filesignatures *fssp, 1194 enum ES_ACTION action) 1195 { 1196 int fscnt; 1197 filesig_vers_t version; 1198 struct filesig *fsgp, *fsgpnext; 1199 1200 if (ess->es_same_endian) 1201 return (ELFSIGN_SUCCESS); 1202 1203 if (ES_ACTISUPDATE(action)) 1204 fscnt = fssp->filesig_cnt; 1205 fssp->filesig_cnt = elfsign_switch_uint32(fssp->filesig_cnt); 1206 if (!ES_ACTISUPDATE(action)) 1207 fscnt = fssp->filesig_cnt; 1208 1209 fsgp = &(fssp)->filesig_sig; 1210 for (; fscnt > 0; fscnt--, fsgp = fsgpnext) { 1211 if (ES_ACTISUPDATE(action)) { 1212 version = fsgp->filesig_version; 1213 fsgpnext = filesig_next(fsgp); 1214 } 1215 fsgp->filesig_size = 1216 elfsign_switch_uint32(fsgp->filesig_size); 1217 fsgp->filesig_version = 1218 elfsign_switch_uint32(fsgp->filesig_version); 1219 if (!ES_ACTISUPDATE(action)) { 1220 version = fsgp->filesig_version; 1221 fsgpnext = filesig_next(fsgp); 1222 } 1223 switch (version) { 1224 case FILESIG_VERSION1: 1225 case FILESIG_VERSION2: 1226 fsgp->filesig_v1_dnsize = 1227 elfsign_switch_uint32(fsgp->filesig_v1_dnsize); 1228 fsgp->filesig_v1_sigsize = 1229 elfsign_switch_uint32(fsgp->filesig_v1_sigsize); 1230 fsgp->filesig_v1_oidsize = 1231 elfsign_switch_uint32(fsgp->filesig_v1_oidsize); 1232 break; 1233 case FILESIG_VERSION3: 1234 case FILESIG_VERSION4: 1235 fsgp->filesig_v3_time = 1236 elfsign_switch_uint64(fsgp->filesig_v3_time); 1237 fsgp->filesig_v3_dnsize = 1238 elfsign_switch_uint32(fsgp->filesig_v3_dnsize); 1239 fsgp->filesig_v3_sigsize = 1240 elfsign_switch_uint32(fsgp->filesig_v3_sigsize); 1241 fsgp->filesig_v3_oidsize = 1242 elfsign_switch_uint32(fsgp->filesig_v3_oidsize); 1243 break; 1244 default: 1245 cryptodebug("elfsign_switch: failed"); 1246 return (ELFSIGN_FAILED); 1247 } 1248 } 1249 return (ELFSIGN_SUCCESS); 1250 } 1251 1252 /* 1253 * get/put an integer value from/to a buffer, possibly of opposite endianness 1254 */ 1255 void 1256 elfsign_buffer_len(ELFsign_t ess, size_t *ip, uchar_t *cp, 1257 enum ES_ACTION action) 1258 { 1259 uint32_t tmp; 1260 1261 if (!ES_ACTISUPDATE(action)) { 1262 /* fetch integer from buffer */ 1263 (void) memcpy(&tmp, cp, sizeof (tmp)); 1264 if (!ess->es_same_endian) { 1265 tmp = elfsign_switch_uint32(tmp); 1266 } 1267 *ip = tmp; 1268 } else { 1269 /* put integer into buffer */ 1270 tmp = *ip; 1271 if (!ess->es_same_endian) { 1272 tmp = elfsign_switch_uint32(tmp); 1273 } 1274 (void) memcpy(cp, &tmp, sizeof (tmp)); 1275 } 1276 } 1277 1278 char const * 1279 elfsign_strerror(ELFsign_status_t elferror) 1280 { 1281 char const *msg = NULL; 1282 1283 switch (elferror) { 1284 case ELFSIGN_SUCCESS: 1285 msg = gettext("sign or verify of ELF object succeeded"); 1286 break; 1287 case ELFSIGN_FAILED: 1288 msg = gettext("sign or verify of ELF object failed"); 1289 break; 1290 case ELFSIGN_NOTSIGNED: 1291 msg = gettext("ELF object not signed"); 1292 break; 1293 case ELFSIGN_INVALID_CERTPATH: 1294 msg = gettext("cannot access certificate"); 1295 break; 1296 case ELFSIGN_INVALID_ELFOBJ: 1297 msg = gettext("unable to open as an ELF object"); 1298 break; 1299 case ELFSIGN_UNKNOWN: 1300 default: 1301 msg = gettext("Unknown error"); 1302 break; 1303 } 1304 1305 return (msg); 1306 } 1307 1308 boolean_t 1309 elfsign_sig_info(struct filesignatures *fssp, struct ELFsign_sig_info **esipp) 1310 { 1311 struct filesig_extraction fsx; 1312 struct ELFsign_sig_info *esip; 1313 1314 esip = (struct ELFsign_sig_info *) 1315 calloc(1, sizeof (struct ELFsign_sig_info)); 1316 *esipp = esip; 1317 if (esip == NULL) 1318 return (B_FALSE); 1319 1320 switch (filesig_extract(&fssp->filesig_sig, &fsx)) { 1321 case FILESIG_VERSION1: 1322 case FILESIG_VERSION2: 1323 case FILESIG_VERSION3: 1324 case FILESIG_VERSION4: 1325 esip->esi_format = fsx.fsx_format; 1326 esip->esi_signer = strdup(fsx.fsx_signer_DN); 1327 esip->esi_time = fsx.fsx_time; 1328 break; 1329 default: 1330 free(esip); 1331 *esipp = NULL; 1332 } 1333 1334 return (*esipp != NULL); 1335 } 1336 1337 void 1338 elfsign_sig_info_free(struct ELFsign_sig_info *esip) 1339 { 1340 if (esip != NULL) { 1341 free(esip->esi_signer); 1342 free(esip); 1343 } 1344 } 1345