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