static bool boot_verify_compare_sha256(unsigned char *image_ptr, unsigned int image_size, unsigned char *signature_ptr, RSA *rsa) { int ret = -1; bool auth = false; unsigned char *plain_text = NULL; unsigned int digest[8]; plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE); if (plain_text == NULL) { dprintf(CRITICAL, "boot_verifier: Calloc failed during verification\n"); goto cleanup; } /* Calculate SHA256sum */ image_find_digest(image_ptr, image_size, CRYPTO_AUTH_ALG_SHA256, (unsigned char *)&digest); /* Find digest from the image */ ret = image_decrypt_signature_rsa(signature_ptr, plain_text, rsa); dprintf(SPEW, "boot_verifier: Return of RSA_public_decrypt = %d\n", ret); ret = verify_digest(plain_text, (unsigned char*)digest, SHA256_SIZE); if(ret == 0) { auth = true; } cleanup: if (plain_text != NULL) free(plain_text); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); return auth; }
/* Decode the encoded SPA data. */ int fko_decode_spa_data(fko_ctx_t ctx) { char *tbuf, *ndx; int t_size, i, res; /* Array of function pointers to SPA field parsing functions */ int (*field_parser[FIELD_PARSERS])(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) = { parse_rand_val, /* Extract random value */ parse_username, /* Extract username */ parse_timestamp, /* Client timestamp */ parse_version, /* SPA version */ parse_msg_type, /* SPA msg type */ parse_msg, /* SPA msg string */ parse_nat_msg, /* SPA NAT msg string */ parse_server_auth, /* optional server authentication method */ parse_client_timeout /* client defined timeout */ }; if (! is_valid_encoded_msg_len(ctx->encoded_msg_len)) return(FKO_ERROR_INVALID_DATA_DECODE_MSGLEN_VALIDFAIL); /* Make sure there are no non-ascii printable chars */ for (i=0; i < (int)strnlen(ctx->encoded_msg, MAX_SPA_ENCODED_MSG_SIZE); i++) if(isprint((int)(unsigned char)ctx->encoded_msg[i]) == 0) return(FKO_ERROR_INVALID_DATA_DECODE_NON_ASCII); /* Make sure there are enough fields in the SPA packet * delimited with ':' chars */ ndx = ctx->encoded_msg; if (num_fields(ndx) < MIN_SPA_FIELDS) return(FKO_ERROR_INVALID_DATA_DECODE_LT_MIN_FIELDS); ndx += last_field(ndx); t_size = strnlen(ndx, SHA512_B64_LEN+1); /* Validate digest length */ res = is_valid_digest_len(t_size, ctx); if(res != FKO_SUCCESS) return res; if(ctx->digest != NULL) free(ctx->digest); /* Copy the digest into the context and terminate the encoded data * at that point so the original digest is not part of the * encoded string. */ ctx->digest = strdup(ndx); if(ctx->digest == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Chop the digest off of the encoded_msg bucket... */ bzero((ndx-1), t_size); ctx->encoded_msg_len -= t_size+1; /* Make a tmp bucket for processing base64 encoded data and * other general use. */ tbuf = calloc(1, FKO_ENCODE_TMP_BUF_SIZE); if(tbuf == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Can now verify the digest. */ res = verify_digest(tbuf, t_size, ctx); if(res != FKO_SUCCESS) { free(tbuf); return(FKO_ERROR_DIGEST_VERIFICATION_FAILED); } /* Now we will work through the encoded data and extract (and base64- * decode where necessary), the SPA data fields and populate the context. */ ndx = ctx->encoded_msg; for (i=0; i < FIELD_PARSERS; i++) { res = (*field_parser[i])(tbuf, &ndx, &t_size, ctx); if(res != FKO_SUCCESS) { free(tbuf); return res; } } /* Done with the tmp buffer. */ free(tbuf); /* Call the context initialized. */ ctx->initval = FKO_CTX_INITIALIZED; FKO_SET_CTX_INITIALIZED(ctx); return(FKO_SUCCESS); }