void DNSUpdate::addDHCID(const char* duid, int duidlen) { DnsRR rr; rr.NAME = domainname(_hostname, *zoneroot); rr.TYPE = qtype_getcode("DHCID", false); rr.TTL = txt_to_int(ttl); char input_buf[512]; char output_buf[35]; // identifier-type code (2) + digest type code (1) + digest (SHA-256 = 32 bytes) memcpy(input_buf, duid, duidlen); // memcpy(input_buf+duidlen, rr.NAME.c_str(), strlen((const char*)rr.NAME.c_str()) ); sha256_buffer(input_buf, duidlen + strlen((const char*)rr.NAME.c_str() ), output_buf+3); output_buf[0] = 0; output_buf[1] = 2; // identifier-type code: 0x0002 - DUID used as client identifier output_buf[2] = 1; // digest type = 1 (SHA-256) message->authority.push_back(rr); }
static char *virLockManagerLockDaemonDiskLeaseName(const char *path) { unsigned char buf[SHA256_DIGEST_SIZE]; char *ret; size_t i; if (!(sha256_buffer(path, strlen(path), buf))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to compute sha256 checksum")); return NULL; } if (VIR_ALLOC_N(ret, (SHA256_DIGEST_SIZE * 2) + 1) < 0) return NULL; for (i = 0; i < SHA256_DIGEST_SIZE; i++) { ret[i*2] = hex[(buf[i] >> 4) & 0xf]; ret[(i*2)+1] = hex[buf[i] & 0xf]; } ret[(SHA256_DIGEST_SIZE * 2) + 1] = '\0'; return ret; }
static u2fh_rc _u2fh_register (u2fh_devs * devs, const char *challenge, const char *origin, char **response, size_t * response_len, u2fh_cmdflags flags) { unsigned char data[V2CHALLEN + HOSIZE]; unsigned char buf[MAXDATASIZE]; char bd[2048]; size_t bdlen = sizeof (bd); size_t len; int rc = U2FH_JSON_ERROR; char chalb64[256]; size_t challen = sizeof (chalb64); int iterations = 0; rc = get_fixed_json_data (challenge, "challenge", chalb64, &challen); if (rc != U2FH_OK) { return rc; } rc = prepare_browserdata (chalb64, origin, REGISTER_TYP, bd, &bdlen); if (rc != U2FH_OK) return rc; sha256_buffer (bd, bdlen, data); prepare_origin (challenge, data + V2CHALLEN); /* FIXME: Support asynchronous usage, through a new u2fh_cmdflags flag. */ do { struct u2fdevice *dev; if (iterations++ > 15) { return U2FH_TIMEOUT_ERROR; } for (dev = devs->first; dev != NULL; dev = dev->next) { len = MAXDATASIZE; rc = send_apdu (devs, dev->id, U2F_REGISTER, data, sizeof (data), flags & U2FH_REQUEST_USER_PRESENCE ? 3 : 0, buf, &len); if (rc != U2FH_OK) { return rc; } else if (len != 2) { break; } } if (len != 2) { break; } Sleep (1000); } while ((flags & U2FH_REQUEST_USER_PRESENCE) && len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0); if (len != 2) { prepare_response (buf, len - 2, bd, response, response_len); return U2FH_OK; } return U2FH_TRANSPORT_ERROR; }
/* Function to verify a given image and signature. Reference implementation in the Little Kernel source in "platform/msm_shared/image_verify.c" Returns -1 if somethings fails otherwise 0 */ int verify_image(unsigned char *image_ptr, unsigned char *signature_ptr, unsigned int image_size) { X509 *x509_certificate = NULL; EVP_PKEY *pub_key = NULL; RSA *rsa_key = NULL; unsigned char *plain_text = NULL; unsigned char digest[65]; unsigned int hash_size = SHA256_SIZE; int ret = 0; /* Load certificate */ FILE *fcert; fcert = fopen("prodcert.pem", "rb"); if (fcert == NULL){ fclose(fcert); std::cerr << "[ ERROR ] Missing certificate" << std::endl; ret = -1; goto cleanup; } x509_certificate = PEM_read_X509(fcert, NULL, NULL, NULL); fclose(fcert); /* Obtain RSA key */ pub_key = X509_get_pubkey(x509_certificate); rsa_key = EVP_PKEY_get1_RSA(pub_key); if (rsa_key == NULL){ std::cerr << "[ ERROR ] Couldn't obtain key from certificate" << std::endl; ret = -1; goto cleanup; } /* Create buffer for decrypted hash */ plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE); if (plain_text == NULL) { std::cerr << "[ ERROR ] calloc failed during verification" << std::endl; ret = -1; goto cleanup; } /* Decrypt hash */ RSA_public_decrypt(SIGNATURE_SIZE, signature_ptr, plain_text, rsa_key, RSA_PKCS1_PADDING); /* Hash the image */ sha256_buffer(image_ptr, image_size, digest); /* Check if signature is equal to the calculated hash */ if (memcmp(plain_text, digest, hash_size) != 0) { std::cerr << std::endl << "[ ERROR ] Invalid signature" << std::endl; ret = -1; goto cleanup; } else { std::cerr << std::endl << "[ SUCCESS ] The signature is valid!" << std::endl; } /* Cleanup after complete usage of openssl - cached data and objects */ cleanup: if (rsa_key != NULL) RSA_free(rsa_key); if (x509_certificate != NULL) X509_free(x509_certificate); if (pub_key != NULL) EVP_PKEY_free(pub_key); if (plain_text != NULL) free(plain_text); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); return ret; }
/* Returns -1 if somethings fails otherwise 0 */ int sign_image(char* in, char* out){ /* An int is enough because the partitions shouldn't be bigger than 4GB */ int finalimagesize = 0; /* Load an image at given path */ FILE *imageinput; imageinput = fopen(in, "rb"); if (imageinput == NULL){ std::cerr << "[ ERROR ] Image does not exist at given location" << std::endl; return -1; } /* Check if file has contents */ unsigned imagefilesize = get_file_size(imageinput); if (imagefilesize == 0){ std::cerr << "[ ERROR ] Image has no size" << std::endl; return -1; } /* Extract image header first to determine if the final image is bigger than the orignal */ boot_img_hdr* hdr = NULL; hdr = (boot_img_hdr*)malloc(sizeof(boot_img_hdr)); fread(hdr, sizeof(boot_img_hdr), 1, imageinput); /* Reposition pointer at start */ fseek(imageinput, 0, SEEK_SET); /* Check if image is an Android bootimage */ if (memcmp((char*)hdr->magic, "ANDROID!", 8) != 0){ std::cerr << "[ ERROR ] File is not an Android boot image" << std::endl; return -1; } /* Load necessary variables from header and delete header */ unsigned kernel_actual; unsigned ramdisk_actual; unsigned imagesize_actual; unsigned dt_actual; unsigned page_size = hdr->page_size; unsigned page_mask = hdr->page_size - 1; kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask); ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask); dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask); free(hdr); /* Calculate size of the "real" image */ imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual); /* If the "real" image is bigger than the file, the file is probably corrupted */ if (imagefilesize < imagesize_actual){ std::cerr << "[ ERROR ] File is invalid (is it corrupted?)" << std::endl; return -1; } /* If the file is smaller than the "real" image + one page, a buffer with the size of the image would be too small we need allocate a new bigger one */ if (imagefilesize < imagesize_actual + page_size){ finalimagesize = imagefilesize + page_size; } else { finalimagesize = imagefilesize; } /* Load image in buffer and close file */ unsigned char* image = NULL; image = (unsigned char*)malloc(finalimagesize); fread(image, 1, imagefilesize, imageinput); fclose(imageinput); /* Create output file */ FILE *imageoutput; imageoutput = fopen(out, "wb"); if (imageoutput == NULL){ std::cerr << "[ ERROR ] Can't write output image to disk" << std::endl; return -1; } /* Hash the real image */ unsigned char hash[65]; unsigned char signature[SIGNATURE_SIZE]; memset(signature, 0, SIGNATURE_SIZE); sha256_buffer(image, imagesize_actual, hash); /* Create signature with given hash */ int sig = create_signature(hash, signature); /* If the signature is created successfully AND the signature passes the check, the signature will be written into the image buffer, which will written to the output file */ if (sig != -1){ std::cerr << std::endl << "[ STATUS ] Checking created signature... "; if (verify_image(image, signature, imagesize_actual) == 0){ memcpy(image + imagesize_actual, signature, SIGNATURE_SIZE); fwrite(image, finalimagesize, 1, imageoutput); } } /* Cleanup */ fclose(imageoutput); free(image); /* Final check of the output file */ std::cerr << std::endl << "[ STATUS ] Checking created image... "; check_image(out); return 0; }
/** * u2fh_authenticate: * @devs: a device handle, from u2fh_devs_init() and u2fh_devs_discover(). * @challenge: string with JSON data containing the challenge. * @origin: U2F origin URL. * @response: pointer to output string with JSON data. * @flags: set of ORed #u2fh_cmdflags values. * * Perform the U2F Authenticate operation. * * Returns: On success %U2FH_OK (integer 0) is returned, and on errors * an #u2fh_rc error code. */ u2fh_rc u2fh_authenticate (u2fh_devs * devs, const char *challenge, const char *origin, char **response, u2fh_cmdflags flags) { unsigned char data[CHALLBINLEN + HOSIZE + MAXKHLEN + 1]; unsigned char buf[MAXDATASIZE]; char bd[2048]; size_t bdlen = sizeof (bd); size_t len; int rc; char chalb64[256]; size_t challen = sizeof (chalb64); char khb64[256]; size_t kh64len = sizeof (khb64); base64_decodestate b64; size_t khlen; int skip_devices[devs->num_devices]; int skipped = 0; int iterations = 0; memset (skip_devices, 0, sizeof (skip_devices)); rc = get_fixed_json_data (challenge, "challenge", chalb64, &challen); if (rc != U2FH_OK) return rc; rc = prepare_browserdata (chalb64, origin, AUTHENTICATE_TYP, bd, &bdlen); if (rc != U2FH_OK) return rc; sha256_buffer (bd, bdlen, data); prepare_origin (challenge, data + CHALLBINLEN); /* confusion between key_handle and keyHandle */ rc = get_fixed_json_data (challenge, "keyHandle", khb64, &kh64len); if (rc != U2FH_OK) return rc; base64_init_decodestate (&b64); khlen = base64_decode_block (khb64, kh64len, data + HOSIZE + CHALLBINLEN + 1, &b64); data[HOSIZE + CHALLBINLEN] = khlen; /* FIXME: Support asynchronous usage, through a new u2fh_cmdflags flag. */ do { int i; if (iterations++ > 15) { return U2FH_TIMEOUT_ERROR; } for (i = 0; i < devs->num_devices; i++) { unsigned char tmp_buf[MAXDATASIZE]; if (skip_devices[i] != 0) { continue; } if (!devs->devs[i].is_alive) { skipped++; skip_devices[i] = 1; continue; } len = MAXDATASIZE; rc = send_apdu (devs, i, U2F_AUTHENTICATE, data, HOSIZE + CHALLBINLEN + khlen + 1, flags & U2FH_REQUEST_USER_PRESENCE ? 3 : 7, tmp_buf, &len); if (rc != U2FH_OK) { return rc; } else if (len != 2) { memcpy (buf, tmp_buf, len); break; } else if (memcmp (tmp_buf, NOTSATISFIED, 2) != 0) { skipped++; skip_devices[i] = 2; continue; } memcpy (buf, tmp_buf, len); } if (len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0) { Sleep (1000); } } while ((flags & U2FH_REQUEST_USER_PRESENCE) && len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0); if (len == 2 && memcmp (buf, NOTSATISFIED, 2) != 0) { return U2FH_AUTHENTICATOR_ERROR; } if (len != 2) { prepare_response (buf, len - 2, bd, challenge, response); } return U2FH_OK; }