static int authcheck_sha1(aClient *cptr, anAuthStruct *as, char *para) { char buf[512]; int i, r; char *saltstr, *hashstr; if (!para) return -1; r = parsepass(as->data, &saltstr, &hashstr); if (r) { /* New method with salt: b64(SHA1(SHA1(<pass>)+salt)) */ char result1[MAXSALTLEN+20+1]; char result2[20]; char rsalt[MAXSALTLEN+1]; int rsaltlen; #ifndef _WIN32 SHA_CTX hash; #else HCRYPTPROV hProv; HCRYPTHASH hHash; DWORD size = 20; #endif /* First, decode the salt to something real... */ rsaltlen = b64_decode(saltstr, rsalt, sizeof(rsalt)); if (rsaltlen <= 0) return -1; #ifdef _WIN32 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return -1; #endif /* Then hash the password (1st round)... */ #ifndef _WIN32 SHA1_Init(&hash); SHA1_Update(&hash, para, strlen(para)); SHA1_Final(result1, &hash); #else if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL; if (!CryptHashData(hHash, para, strlen(para), 0)) return NULL; if (!CryptGetHashParam(hHash, HP_HASHVAL, result1, &size, 0)) return NULL; CryptDestroyHash(hHash); #endif /* Add salt to result */ memcpy(result1+20, rsalt, rsaltlen); /* b64_decode already made sure bounds are ok */ /* Then hash it all together again (2nd round)... */ #ifndef _WIN32 SHA1_Init(&hash); SHA1_Update(&hash, result1, rsaltlen+20); SHA1_Final(result2, &hash); #else if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL; if (!CryptHashData(hHash, result1, 20+rsaltlen, 0)) return NULL; if (!CryptGetHashParam(hHash, HP_HASHVAL, result2, &size, 0)) return NULL; CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); #endif /* Then base64 encode it all and we are done... */ if ((i = b64_encode(result2, sizeof(result2), buf, sizeof(buf)))) { if (!strcmp(buf, hashstr)) return 2; else return -1; } else return -1; } else { /* OLD auth */ #ifndef _WIN32 if ((i = b64_encode(SHA1(para, strlen(para), NULL), 20, buf, sizeof(buf)))) { if (!strcmp(buf, as->data)) return 2; else return -1; } else return -1; #else HCRYPTPROV hProv; HCRYPTHASH hHash; char buf2[512]; DWORD size = 512; if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return -1; if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return -1; if (!CryptHashData(hHash, para, strlen(para), 0)) return -1; if (!CryptGetHashParam(hHash, HP_HASHVAL, buf, &size, 0)) return -1; CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); b64_encode(buf, 20, buf2, sizeof(buf2)); if (!strcmp(buf2, as->data)) return 2; else return -1; #endif } }
static char *mkpass_sha1(char *para) { static char buf[128]; char result1[20+REALSALTLEN]; char result2[20]; char saltstr[REALSALTLEN]; /* b64 encoded printable string*/ char saltraw[RAWSALTLEN]; /* raw binary */ char xresult[64]; #ifndef _WIN32 SHA_CTX hash; #else HCRYPTPROV hProv; HCRYPTHASH hHash; DWORD size = 20; #endif int i; if (!para) return NULL; /* generate a random salt... */ for (i=0; i < RAWSALTLEN; i++) saltraw[i] = getrandom8(); i = b64_encode(saltraw, RAWSALTLEN, saltstr, REALSALTLEN); if (!i) return NULL; #ifdef _WIN32 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return NULL; #endif /* b64(SHA1(SHA1(<pass>)+salt)) * ^^^^^^^^^^^ * step 1 * ^^^^^^^^^^^^^^^^^^^^^ * step 2 * ^^^^^^^^^^^^^^^^^^^^^^^^^^ * step 3 */ /* STEP 1 */ #ifndef _WIN32 SHA1_Init(&hash); SHA1_Update(&hash, para, strlen(para)); SHA1_Final(result1, &hash); #else if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL; if (!CryptHashData(hHash, para, strlen(para), 0)) return NULL; if (!CryptGetHashParam(hHash, HP_HASHVAL, result1, &size, 0)) return NULL; CryptDestroyHash(hHash); #endif /* STEP 2 */ /* add salt to result */ memcpy(result1+20, saltraw, RAWSALTLEN); /* Then hash it all together */ #ifndef _WIN32 SHA1_Init(&hash); SHA1_Update(&hash, result1, RAWSALTLEN+20); SHA1_Final(result2, &hash); #else if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) return NULL; if (!CryptHashData(hHash, result1, RAWSALTLEN+20, 0)) return NULL; if (!CryptGetHashParam(hHash, HP_HASHVAL, result2, &size, 0)) return NULL; CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); #endif /* STEP 3 */ /* Then base64 encode it all together.. */ i = b64_encode(result2, sizeof(result2), xresult, sizeof(xresult)); if (!i) return NULL; /* Good.. now create the whole string: * $<saltb64d>$<totalhashb64d> */ ircsprintf(buf, "$%s$%s", saltstr, xresult); return buf; }
/** * Sets the data property * * @param data the data property * */ void Authentication::setData(const char*data) { if (data == NULL) { // TBD return; } const char* type = this->getType(); if (strcmp(type,AUTH_TYPE_BASIC) == 0) { char* clearData = NULL; if (encode) { unsigned long len = 0; len = strlen(data); char* tmp = stringdup(data); char* b64tmp2 = new char[(len/3+1)<<2]; len = b64_encode(b64tmp2, tmp, len); char* b64tmp = new char[len + 1]; memset(b64tmp, 0, len + 1); strncpy(b64tmp, b64tmp2, len); if (this->data) { delete [] this->data; this->data = NULL; } this->data = stringdup(b64tmp); clearData = new char[strlen(data) + 1]; sprintf(clearData, data); if (b64tmp2) { delete [] b64tmp2; b64tmp2 = NULL; } if (b64tmp) { delete [] b64tmp; b64tmp = NULL; } if (tmp) { delete [] tmp; tmp = NULL; } } else { unsigned long len = 0; len = strlen(data); char* tmp = stringdup(data); char* b64tmp = new char[len]; len = b64_decode(b64tmp, tmp); clearData = stringdup(b64tmp); if (this->data) { delete [] this->data; this->data = NULL; } //this->data = new char[strlen(clearData) + 1]; //sprintf(this->data, clearData); this->data = stringdup(data); if (tmp) { delete [] tmp; tmp = NULL; } if (b64tmp) { delete [] b64tmp; b64tmp = NULL; } } unsigned int len = strlen(clearData); char* p1 = clearData; bool charFound = false; for (unsigned int k = 0; k < len; k++) { if (*p1 == 0) { break; } else if (*p1 == ':') { charFound = true; p1 = p1 + 1; break; } p1 = p1 + 1; } if (charFound == false) { this->setUsername(clearData); this->setPassword(NULL); } else { char* p2 = p1 - 1; *p2 = 0; if (strlen(clearData) > 0 ) { this->setUsername(clearData); } else { this->setUsername(""); } if (strlen(p1) > 0) { this->setPassword(p1); } else { this->setPassword(""); } } if (clearData) { delete [] clearData; clearData = NULL; } } if (strcmp(type, AUTH_TYPE_MD5) == 0) { if (meta->getFormat() == NULL) { this->setFormat(FORMAT_B64); } this->setUsername(data); this->data = stringdup(data); } }
static void test_1_00() { XTESTS_TEST_INTEGER_EQUAL(0u, b64_encode(NULL, 0, NULL, 0)); }
/* This is needed as a separate function, otherwise we run out of stack!! */ static int execute_unittest() { int ints[1001]; const size_t n = rand() % (sizeof(ints) / sizeof(ints[0])); size_t j; size_t cch; size_t cch2; char *enc; size_t cb; size_t cb2; int *dec; /* Randomise the array */ for(j = 0; j < n; ++j) { ints[j] = rand(); } /* Encode */ cch = b64_encode(&ints[0], n * sizeof(int), NULL, 0); enc = (char*)alloca(cch); cch2 = b64_encode(&ints[0], n * sizeof(int), enc, cch); if( 0 != n && 0 == cch) { fprintf(stderr, "Failed: b64_encode() returned 0\n"); return 1; } else if(cch2 != cch) { fprintf(stderr, "Failed: b64_encode() returned different size to that reported in size determination\n"); return 1; } /* Decode */ cb = b64_decode(enc, cch, NULL, 0); dec = (int*)alloca(cb); cb2 = b64_decode(enc, cch, dec, cb); if( 0 != n && 0 == cb) { fprintf(stderr, "Failed: b64_decode() returned 0\n"); return 1; } else if(cb2 > cb) { fprintf(stderr, "Failed: b64_decode() returned different value than that reported in size determination\n"); return 1; } if(cb < n * sizeof(int)) { fprintf(stderr, "Failed: wrong size: encoded size: %ld; decoded size: %ld\n", (long)(n * sizeof(int)), (long)cb); return 1; } if(0 != memcmp(&ints[0], &dec[0], cb2)) { fprintf(stderr, "Failed: decoded form different from original!\n"); return 1; } return 0; }
/* Prep and encrypt using Rijndael */ static int _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key, const int enc_key_len) { char *plaintext; char *b64ciphertext; unsigned char *ciphertext; int cipher_len; int pt_len; int zero_free_rv = FKO_SUCCESS; if(enc_key_len > RIJNDAEL_MAX_KEYSIZE) return(FKO_ERROR_INVALID_KEY_LEN); if (! is_valid_encoded_msg_len(ctx->encoded_msg_len)) return(FKO_ERROR_INVALID_DATA_ENCRYPT_MSGLEN_VALIDFAIL); switch(ctx->digest_len) { case MD5_B64_LEN: break; case SHA1_B64_LEN: break; case SHA256_B64_LEN: break; case SHA384_B64_LEN: break; case SHA512_B64_LEN: break; default: return(FKO_ERROR_INVALID_DATA_ENCRYPT_DIGESTLEN_VALIDFAIL); } pt_len = ctx->encoded_msg_len + ctx->digest_len + RIJNDAEL_BLOCKSIZE + 2; /* Make a bucket big enough to hold the enc msg + digest (plaintext) * and populate it appropriately. */ plaintext = calloc(1, pt_len); if(plaintext == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); pt_len = snprintf(plaintext, pt_len, "%s:%s", ctx->encoded_msg, ctx->digest); if(! is_valid_pt_msg_len(pt_len)) { if(zero_free(plaintext, pt_len) == FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_ENCRYPT_PTLEN_VALIDFAIL); else return(FKO_ERROR_ZERO_OUT_DATA); } /* Make a bucket for the encrypted version and populate it. */ ciphertext = calloc(1, pt_len + 32); /* Plus padding for salt and Block */ if(ciphertext == NULL) { if(zero_free(plaintext, pt_len) == FKO_SUCCESS) return(FKO_ERROR_MEMORY_ALLOCATION); else return(FKO_ERROR_ZERO_OUT_DATA); } cipher_len = rij_encrypt( (unsigned char*)plaintext, pt_len, (char*)enc_key, enc_key_len, ciphertext, ctx->encryption_mode ); /* Now make a bucket for the base64-encoded version and populate it. */ b64ciphertext = malloc(((cipher_len / 3) * 4) + 8); if(b64ciphertext == NULL) { if(zero_free((char *) ciphertext, pt_len+32) == FKO_SUCCESS && zero_free(plaintext, pt_len) == FKO_SUCCESS) return(FKO_ERROR_MEMORY_ALLOCATION); else return(FKO_ERROR_ZERO_OUT_DATA); } b64_encode(ciphertext, b64ciphertext, cipher_len); strip_b64_eq(b64ciphertext); if(ctx->encrypted_msg != NULL) zero_free_rv = zero_free(ctx->encrypted_msg, strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE)); ctx->encrypted_msg = strdup(b64ciphertext); ctx->encrypted_msg_len = strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE); /* Clean-up */ if(zero_free(plaintext, pt_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free((char *) ciphertext, pt_len+32) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free(b64ciphertext, strnlen(b64ciphertext, MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(ctx->encrypted_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); if(! is_valid_encoded_msg_len(ctx->encrypted_msg_len)) return(FKO_ERROR_INVALID_DATA_ENCRYPT_RESULT_MSGLEN_VALIDFAIL); return(zero_free_rv); }
static int http_connect(URLContext *h, const char *path, const char *hoststr, const char *auth) { HTTPContext *s = h->priv_data; int post, err, ch; char line[1024], *q; /* send http header */ post = h->flags & URL_WRONLY; snprintf(s->buffer, sizeof(s->buffer), "%s %s HTTP/1.0\r\n" "User-Agent: %s\r\n" "Accept: */*\r\n" "Host: %s\r\n" "Authorization: Basic %s\r\n" "\r\n", post ? "POST" : "GET", path, LIBAVFORMAT_IDENT, hoststr, b64_encode(auth)); if (http_write(h, s->buffer, strlen(s->buffer)) < 0) return AVERROR_IO; /* init input buffer */ s->buf_ptr = s->buffer; s->buf_end = s->buffer; s->line_count = 0; s->location[0] = '\0'; if (post) { sleep(1); return 0; } /* wait for header */ q = line; for(;;) { ch = http_getc(s); if (ch < 0) return AVERROR_IO; if (ch == '\n') { /* process line */ if (q > line && q[-1] == '\r') q--; *q = '\0'; #ifdef DEBUG printf("header='%s'\n", line); #endif err = process_line(s, line, s->line_count); if (err < 0) return err; if (err == 0) return 0; s->line_count++; q = line; } else { if ((q - line) < sizeof(line) - 1) *q++ = ch; } } }
int main(void) { /* Simple conversion using b64_encode() and b64_decode(). */ /* Declare an array of bytes to use as the 'binary' blob to encode. */ unsigned char bytes[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; /* Invoke b64_encode() to determine the maximum size of the encoded * string, specifying the argument 0 for the destSize parameter. * * Note: The value returned may be larger than the actual size * required, but will never be smaller. */ size_t cch = b64_encode(&bytes[0], sizeof(bytes), NULL, 0); /* Using the length determined by the call to b64_encode(), create * a buffer of sufficient size. */ char *enc = (char*)malloc(cch); size_t cb; void *dec; size_t i; printf("Converting %u bytes:\n", (unsigned)NUM_ELEMENTS(bytes)); for(i = 0; i != NUM_ELEMENTS(bytes); ++i) { printf(" %d", bytes[i]); } puts(""); /* Perform the encoding. */ cch = b64_encode(&bytes[0], sizeof(bytes), enc, cch); printf("Encoded form: [%.*s]\n", (int)cch, enc); /* Invoke b64_decode() to determine the maximum size of the decoded * blob, specifying the argument 0 for the destLen parameter. * * Note: The value returned may be larger than the actual size * required, but will never be smaller. */ cb = b64_decode(enc, cch, NULL, 0); /* Using the length determined by the call to b64_decode(), create * a buffer of sufficient size. */ dec = malloc(cb); /* Perform the decoding. */ cb = b64_decode(enc, cch, dec, cb); /* Verify that the decoding is exactly the same size and contents as * the encoding. */ assert(cb == sizeof(bytes)); assert(0 == memcmp(&bytes[0], dec, sizeof(bytes))); /* Clean up */ free(dec); free(enc); /* Placate the compiler's warnings. */ ((void)cb); return EXIT_SUCCESS; }
char *_generate_signature_for_parameters(HTTPParameter *first_parameter, HTTPConnection *http_connection) { int parameters_count = 0; HTTPParameter *current_parameter = first_parameter; while(current_parameter != NULL) { parameters_count++; current_parameter = (HTTPParameter *)current_parameter->next_parameter; } HTTPParameter http_parameters[parameters_count]; int i = 0; current_parameter = first_parameter; while(current_parameter != NULL) { http_parameters[i] = *current_parameter; i++; current_parameter = (HTTPParameter *)current_parameter->next_parameter; } // sort parameters alphabetically qsort(http_parameters, parameters_count, sizeof(HTTPParameter), compare_parameters); char *signature_base_string = malloc(sizeof(char) * 500); for(i = 0; i < parameters_count; i++) { current_parameter = &(http_parameters[i]); if(current_parameter->type != HTTPParameterTypeAuthorizationHeader) { sprintf(signature_base_string, "%s%s=%s&", signature_base_string, current_parameter->key, current_parameter->value); } } signature_base_string[strlen(signature_base_string) - 1] = '\0'; // removes last '&' sprintf(signature_base_string, "%s&%s&%s", (http_connection->connection_method == HTTPConnectionMethodPOST ? "POST" : "GET"), _html_escape_string(http_connection->url), _html_escape_string(signature_base_string)); unsigned char sha1_result[30];// = malloc(sizeof(char) * 32); char *key_string = malloc(sizeof(char) * 200); if(current_oauth_token) { sprintf(key_string, "%s&%s", OAUTH_CONSUMER_SECRET, current_oauth_token->oauth_token_secret); } else if(current_access_token) { sprintf(key_string, "%s&%s", OAUTH_CONSUMER_SECRET, current_access_token->access_token_secret); } else { sprintf(key_string, "%s&", OAUTH_CONSUMER_SECRET); } printf("signature_base_string: %s\n", signature_base_string); unsigned int md_len = 30; // result = HMAC(EVP_sha256(), key, 4, data, 28, NULL, NULL); int success = hmac_sha1(key_string, strlen(key_string), signature_base_string, strlen(signature_base_string), sha1_result); // int success = HMAC(EVP_sha1(), key_string, strlen(key_string), signature_base_string, strlen(signature_base_string), sha1_result, &md_len); // if(success != 0) { // printf(" Error generating oauth_signature (HMAC-SHA1). \n"); // return NULL; // } free(key_string); free(signature_base_string); char *final_signature = malloc(sizeof(char) * 100); b64_encode(&sha1_result, final_signature); return final_signature; }
/* Prep and encrypt using gpgme */ int gpg_encrypt(fko_ctx_t ctx, char *enc_key) { int res; char *plain; char *b64cipher; unsigned char *cipher = NULL; size_t cipher_len; /* First make sure we have a recipient key set. */ if(ctx->gpg_recipient == NULL) return(FKO_ERROR_MISSING_GPG_KEY_DATA); /* Make a bucket big enough to hold the enc msg + digest (plaintext) * and populate it appropriately. */ plain = malloc(strlen(ctx->encoded_msg) + strlen(ctx->digest) + 2); if(plain == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); sprintf(plain, "%s:%s", ctx->encoded_msg, ctx->digest); res = gpgme_encrypt(ctx, (unsigned char*)plain, strlen(plain), enc_key, &cipher, &cipher_len ); /* --DSS XXX: Better parsing of what went wrong would be nice :) */ if(res != FKO_SUCCESS) { free(plain); if(cipher) free(cipher); return(res); } /* Now make a bucket for the base64-encoded version and populate it. */ b64cipher = malloc(((cipher_len / 3) * 4) + 8); if(b64cipher == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); b64_encode(cipher, b64cipher, cipher_len); strip_b64_eq(b64cipher); ctx->encrypted_msg = strdup(b64cipher); /* Clean-up */ free(plain); free(cipher); free(b64cipher); if(ctx->encrypted_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); return(FKO_SUCCESS); }
int sign_message(struct s3_message* mesg, const char* user, const char * key) { int sign_str_len = 0; char *sign_str; char date[1024]; struct s3_header_object *amz; struct list *amz_headers; char digest[SHA1_DIGEST_LENGTH]; char string[SHA1_DIGEST_LENGTH*2]; int result; memset(digest, 0, SHA1_DIGEST_LENGTH); memset(string, 0, SHA1_DIGEST_LENGTH*2); switch(mesg->type) { case S3_MESG_GET: sign_str_len += 4; break; case S3_MESG_POST: sign_str_len += 5; break; case S3_MESG_PUT: sign_str_len += 4; break; case S3_MESG_DELETE: sign_str_len += 7; break; case S3_MESG_HEAD: sign_str_len += 5; break; case S3_MESG_COPY: sign_str_len += 4; break; default: return -1; } if(mesg->content_md5) sign_str_len += strlen(mesg->content_md5); sign_str_len += 1; if(mesg->content_type) sign_str_len += strlen(mesg->content_type); sign_str_len += 1; strftime(date, 1024, "%a, %d %b %Y %H:%M:%S %Z", gmtime(&mesg->date)); sign_str_len += strlen(date) + 1; if(mesg->amz_headers) { list_first_item(mesg->amz_headers); while( (amz = (struct s3_header_object *)list_next_item(mesg->amz_headers)) ) { if(amz->type < S3_HEADER_CUSTOM) continue; switch(amz->type) { case S3_HEADER_CUSTOM: if(!amz->custom_type) return -1; sign_str_len += strlen(amz->custom_type) + 1; break; default: sign_str_len += strlen(s3_get_header_string(amz->type, amz->custom_type)) + 1; break; } if(!amz->value) return -1; sign_str_len += strlen(amz->value) + 1; } } if(!mesg->bucket || !mesg->path) { return -1; } sign_str_len += 1 + strlen(mesg->bucket) + 1 + strlen(mesg->path) + 1; sign_str = malloc(sign_str_len); if(!sign_str) return -1; memset(sign_str, 0, sign_str_len); switch(mesg->type) { case S3_MESG_GET: sprintf(sign_str, "GET\n"); break; case S3_MESG_POST: sprintf(sign_str, "POST\n"); break; case S3_MESG_PUT: sprintf(sign_str, "PUT\n"); break; case S3_MESG_DELETE: sprintf(sign_str, "DELETE\n"); break; case S3_MESG_HEAD: sprintf(sign_str, "HEAD\n"); break; case S3_MESG_COPY: sprintf(sign_str, "PUT\n"); break; } if(mesg->content_md5) sprintf(sign_str, "%s%s\n", sign_str,mesg->content_md5); else sprintf(sign_str, "%s\n", sign_str); if(mesg->content_type) sprintf(sign_str, "%s%s\n", sign_str, mesg->content_type); else sprintf(sign_str, "%s\n", sign_str); sprintf(sign_str, "%s%s", sign_str, date); if(mesg->amz_headers) { amz_headers = list_sort(list_duplicate(mesg->amz_headers), &s3_header_object_comp); list_first_item(amz_headers); { int c_type = -1; char* c_ctype = NULL; while( (amz = (struct s3_header_object *)list_next_item(amz_headers)) ) { if(amz->type < S3_HEADER_CUSTOM) continue; if(c_type != amz->type) { c_type = amz->type; c_ctype = amz->custom_type; sprintf(sign_str, "%s\n%s:%s", sign_str, s3_get_header_string(amz->type, amz->custom_type), amz->value); } else if(c_type == S3_HEADER_CUSTOM && strcmp(c_ctype, amz->custom_type)) { c_ctype = amz->custom_type; sprintf(sign_str, "%s\n%s:%s", sign_str, amz->custom_type, amz->value); } else { sprintf(sign_str, "%s,%s", sign_str, amz->value); } } } list_delete(amz_headers); } sprintf(sign_str, "%s\n/%s%s", sign_str, mesg->bucket, mesg->path); if((result = hmac_sha1(sign_str, strlen(sign_str), key, strlen(key), (unsigned char*)digest))) return result; hmac_sha1(sign_str, strlen(sign_str), key, strlen(key), (unsigned char*)digest); b64_encode(digest, SHA1_DIGEST_LENGTH, string, SHA1_DIGEST_LENGTH*2); sprintf(mesg->authorization, "AWS %s:%s", user, string); free(sign_str); return 0; }
static void bookmark_save_one(FILE *fp, url_t *url) { if (url == gvLocalUrl) fprintf(fp, "local"); else if (url == gvDefaultUrl) fprintf(fp, "default"); else { fprintf(fp, "machine %s://%s", url->protocol ? url->protocol : "ftp", url->hostname); if (url->port != -1) fprintf(fp, ":%d", url->port); if (url->alias) { char *a = xquote_chars(url->alias, "\'\""); fprintf(fp, " alias '%s'", a); free(a); } } if (url_isanon(url) && url->password && strcmp(url->password, gvAnonPasswd) == 0) fprintf(fp, "\n anonymous"); else if (url->username) { fprintf(fp, "\n login %s", url->username); if (url->password) { if (url_isanon(url)) fprintf(fp, " password %s", url->password); else { char *cq = NULL; if (b64_encode(url->password, strlen(url->password), &cq) != -1) { fprintf(fp, " password [base64]%s", cq); free(cq); } } } } if (url->directory) fprintf(fp, " cwd '%s'", url->directory); if (url->protlevel) fprintf(fp, " prot %s", url->protlevel); if (url->mech) { char *mech_string = stringify_list(url->mech); if (mech_string) { fprintf(fp, " mech '%s'", mech_string); free(mech_string); } } if (url->pasvmode != -1) fprintf(fp, " passive %s", url->pasvmode ? "true" : "false"); if (url->sftp_server) fprintf(fp, " sftp %s", url->sftp_server); if (url->noupdate) fprintf(fp, " noupdate"); fprintf(fp, "\n\n"); }
static int sign(const char *msgfile) { struct seckey skey; struct sig sig = { .pkalg = "Ed", }; struct stat st; char buf[512]; void *pubkey = buf; long mlen; void *m; int mfd; if (!get_base64_file(seckeyfile, &skey, sizeof(skey), buf, sizeof(buf)) || memcmp(skey.pkalg, "Ed", 2) != 0) { fprintf(stderr, "Failed to decode secret key\n"); return 1; } if (skey.kdfrounds) { fprintf(stderr, "Password protected secret keys are not supported\n"); return 1; } mfd = open(msgfile, O_RDONLY, 0); if (mfd < 0 || fstat(mfd, &st) < 0 || (m = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, mfd, 0)) == MAP_FAILED) { if (mfd >= 0) close(mfd); perror("Cannot open message file"); return 1; } mlen = st.st_size; memcpy(sig.fingerprint, skey.fingerprint, sizeof(sig.fingerprint)); edsign_sec_to_pub(pubkey, skey.seckey); edsign_sign(sig.sig, pubkey, skey.seckey, m, mlen); munmap(m, mlen); close(mfd); if (b64_encode(&sig, sizeof(sig), buf, sizeof(buf)) < 0) return 1; write_file(sigfile, sig.fingerprint, "signed by key", buf); return 0; } static int fingerprint(void) { struct seckey skey; struct pubkey pkey; struct sig sig; char buf[512]; uint8_t *fp; if (seckeyfile && get_base64_file(seckeyfile, &skey, sizeof(skey), buf, sizeof(buf))) fp = skey.fingerprint; else if (pubkeyfile && get_base64_file(pubkeyfile, &pkey, sizeof(pkey), buf, sizeof(buf))) fp = pkey.fingerprint; else if (sigfile && get_base64_file(sigfile, &sig, sizeof(sig), buf, sizeof(buf))) fp = sig.fingerprint; else return 1; fprintf(stdout, "%"PRIx64"\n", fingerprint_u64(fp)); return 0; } static int generate(void) { struct seckey skey = { .pkalg = "Ed", .kdfalg = "BK", .kdfrounds = 0, }; struct pubkey pkey = { .pkalg = "Ed", }; struct sha512_state s; char buf[512]; FILE *f; f = fopen("/dev/urandom", "r"); if (!f || fread(skey.fingerprint, sizeof(skey.fingerprint), 1, f) != 1 || fread(skey.seckey, EDSIGN_SECRET_KEY_SIZE, 1, f) != 1 || fread(skey.salt, sizeof(skey.salt), 1, f) != 1) { fprintf(stderr, "Can't read data from /dev/urandom\n"); return 1; } if (f) fclose(f); ed25519_prepare(skey.seckey); edsign_sec_to_pub(skey.seckey + 32, skey.seckey); sha512_init(&s); sha512_add(&s, skey.seckey, sizeof(skey.seckey)); memcpy(skey.checksum, sha512_final_get(&s), sizeof(skey.checksum)); if (b64_encode(&skey, sizeof(skey), buf, sizeof(buf)) < 0) return 1; write_file(seckeyfile, skey.fingerprint, "public key", buf); memcpy(pkey.fingerprint, skey.fingerprint, sizeof(pkey.fingerprint)); memcpy(pkey.pubkey, skey.seckey + 32, sizeof(pkey.pubkey)); if (b64_encode(&pkey, sizeof(pkey), buf, sizeof(buf)) < 0) return 1; write_file(pubkeyfile, pkey.fingerprint, "private key", buf); return 0; } static int usage(const char *cmd) { fprintf(stderr, "Usage: %s <command> <options>\n" "Commands:\n" " -V: verify (needs at least -m and -p|-P)\n" " -S: sign (needs at least -m and -s)\n" " -F: print key fingerprint of public/secret key or signature\n" " -G: generate a new keypair\n" "Options:\n" " -c <comment>: add comment to keys\n" " -m <file>: message file\n" " -p <file>: public key file (verify/fingerprint only)\n" " -P <path>: public key directory (verify only)\n" " -q: quiet (do not print verification result, use return code only)\n" " -s <file>: secret key file (sign/fingerprint only)\n" " -x <file>: signature file (defaults to <message file>.sig)\n" "\n", cmd); return 1; } static void set_cmd(const char *prog, int val) { if (cmd != CMD_NONE) exit(usage(prog)); cmd = val; } int main(int argc, char **argv) { const char *msgfile = NULL; int ch; while ((ch = getopt(argc, argv, "FGSVc:m:P:p:qs:x:")) != -1) { switch (ch) { case 'V': set_cmd(argv[0], CMD_VERIFY); break; case 'S': set_cmd(argv[0], CMD_SIGN); break; case 'F': set_cmd(argv[0], CMD_FINGERPRINT); break; case 'G': set_cmd(argv[0], CMD_GENERATE); break; case 'c': comment = optarg; break; case 'm': msgfile = optarg; break; case 'P': pubkeydir = optarg; break; case 'p': pubkeyfile = optarg; break; case 's': seckeyfile = optarg; break; case 'x': sigfile = optarg; break; case 'q': quiet = true; break; default: return usage(argv[0]); } } if (!sigfile && msgfile) { char *buf = alloca(strlen(msgfile) + 5); if (!strcmp(msgfile, "-")) { fprintf(stderr, "Need signature file when reading message from stdin\n"); return 1; } sprintf(buf, "%s.sig", msgfile); sigfile = buf; } switch (cmd) { case CMD_VERIFY: if ((!pubkeyfile && !pubkeydir) || !msgfile) return usage(argv[0]); return verify(msgfile); case CMD_SIGN: if (!seckeyfile || !msgfile || !sigfile) return usage(argv[0]); return sign(msgfile); case CMD_FINGERPRINT: if (!!seckeyfile + !!pubkeyfile + !!sigfile != 1) { fprintf(stderr, "Need one secret/public key or signature\n"); return usage(argv[0]); } return fingerprint(); case CMD_GENERATE: if (!seckeyfile || !pubkeyfile) return usage(argv[0]); return generate(); default: return usage(argv[0]); } }
static char * packStructure(char *serviceName, char *dest, char *trans_id, char *payload, char *contentType, unsigned int payload_len) { msgpack_sbuffer sbuf; msgpack_packer pk; char* b64buffer = NULL; size_t encodeSize = 0; char source[MAX_PARAMETERNAME_LEN/2] = {'\0'}; int msg_type = 4; CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, LMLite %s ENTER\n", __FUNCTION__ )); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, deviceMAC *********:%s\n",deviceMAC)); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, serviceName :%s\n",serviceName)); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, dest :%s\n",dest)); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, transaction_id :%s\n",trans_id)); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, contentType :%s\n",contentType)); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, payload_len :%d\n",payload_len)); snprintf(source, sizeof(source), "mac:%s/%s", deviceMAC, serviceName); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, Received DeviceMac from Atom side: %s\n",deviceMAC)); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, Source derived is %s\n", source)); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, <======== Start of packStructure ======>\n")); // Start of msgpack encoding CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, -----------Start of msgpack encoding------------\n")); msgpack_sbuffer_init(&sbuf); msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); msgpack_pack_map(&pk, WEBPA_MAP_SIZE); msgpack_pack_str(&pk, strlen(WEBPA_MSG_TYPE)); msgpack_pack_str_body(&pk, WEBPA_MSG_TYPE,strlen(WEBPA_MSG_TYPE)); msgpack_pack_int(&pk, msg_type); msgpack_pack_str(&pk, strlen(WEBPA_SOURCE)); msgpack_pack_str_body(&pk, WEBPA_SOURCE,strlen(WEBPA_SOURCE)); msgpack_pack_str(&pk, strlen(source)); msgpack_pack_str_body(&pk, source,strlen(source)); msgpack_pack_str(&pk, strlen(WEBPA_DESTINATION)); msgpack_pack_str_body(&pk, WEBPA_DESTINATION,strlen(WEBPA_DESTINATION)); msgpack_pack_str(&pk, strlen(dest)); msgpack_pack_str_body(&pk, dest,strlen(dest)); msgpack_pack_str(&pk, strlen(WEBPA_TRANSACTION_ID)); msgpack_pack_str_body(&pk, WEBPA_TRANSACTION_ID,strlen(WEBPA_TRANSACTION_ID)); msgpack_pack_str(&pk, strlen(trans_id)); msgpack_pack_str_body(&pk, trans_id,strlen(trans_id)); msgpack_pack_str(&pk, strlen(WEBPA_PAYLOAD)); msgpack_pack_str_body(&pk, WEBPA_PAYLOAD,strlen(WEBPA_PAYLOAD)); if(strcmp(contentType,"avro/binary") == 0) { CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, msg->payload binary\n")); msgpack_pack_bin(&pk, payload_len); msgpack_pack_bin_body(&pk, payload, payload_len); } else // string: "contentType :application/json" { CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, msg->payload string\n")); msgpack_pack_str(&pk, strlen(payload)); msgpack_pack_str_body(&pk, payload,strlen(payload)); } msgpack_pack_str(&pk, strlen(CONTENT_TYPE)); msgpack_pack_str_body(&pk, CONTENT_TYPE,strlen(CONTENT_TYPE)); msgpack_pack_str(&pk, strlen(contentType)); msgpack_pack_str_body(&pk, contentType,strlen(contentType)); /*if(consoleDebugEnable) fprintf(stderr, "RDK_LOG_DEBUG,msgpack encoded data contains %d bytes and data is : %s\n",(int)sbuf.size,sbuf.data);*/ CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,-----------End of msgpack encoding------------\n")); // End of msgpack encoding // Start of Base64 Encode CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,-----------Start of Base64 Encode ------------\n")); encodeSize = b64_get_encoded_buffer_size( sbuf.size ); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,encodeSize is %d\n", (int)encodeSize)); b64buffer = malloc(encodeSize + 1); // one byte extra for terminating NULL byte b64_encode((const uint8_t *)sbuf.data, sbuf.size, (uint8_t *)b64buffer); b64buffer[encodeSize] = '\0' ; /*if(consoleDebugEnable) { int i; fprintf(stderr, "RDK_LOG_DEBUG,\n\n b64 encoded data is : "); for(i = 0; i < encodeSize; i++) fprintf(stderr,"%c", b64buffer[i]); fprintf(stderr,"\n\n"); }*/ //CcspLMLiteTrace(("RDK_LOG_DEBUG,\nb64 encoded data length is %d\n",i)); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,---------- End of Base64 Encode -------------\n")); // End of Base64 Encode CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,Destroying sbuf.....\n")); msgpack_sbuffer_destroy(&sbuf); //CcspLMLiteTrace(("RDK_LOG_DEBUG,Final Encoded data: %s\n",b64buffer)); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,Final Encoded data length: %d\n",(int)strlen(b64buffer))); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG,<======== End of packStructure ======>\n")); CcspLMLiteConsoleTrace(("RDK_LOG_DEBUG, LMLite %s EXIT\n", __FUNCTION__ )); return b64buffer; }
static rapidjson::Value* field2json(const Message *msg, const FieldDescriptor *field, rapidjson::Value::AllocatorType& allocator) { const Reflection *ref = msg->GetReflection(); const bool repeated = field->is_repeated(); size_t array_size = 0; if (repeated) { array_size = ref->FieldSize(*msg, field); } rapidjson::Value* json = NULL; if (repeated) { json = new rapidjson::Value(rapidjson::kArrayType); } switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_DOUBLE: if (repeated) { for (size_t i = 0; i != array_size; ++i) { double value = ref->GetRepeatedDouble(*msg, field, i); rapidjson::Value v(value); json->PushBack(v, allocator); } } else { json = new rapidjson::Value(ref->GetDouble(*msg, field)); } break; case FieldDescriptor::CPPTYPE_FLOAT: if (repeated) { for (size_t i = 0; i != array_size; ++i) { float value = ref->GetRepeatedFloat(*msg, field, i); rapidjson::Value v(value); json->PushBack(v, allocator); } } else { json = new rapidjson::Value(ref->GetFloat(*msg, field)); } break; case FieldDescriptor::CPPTYPE_INT64: if (repeated) { for (size_t i = 0; i != array_size; ++i) { int64_t value = ref->GetRepeatedInt64(*msg, field, i); rapidjson::Value v(value); json->PushBack(v, allocator); } } else { json = new rapidjson::Value(static_cast<int64_t>(ref->GetInt64(*msg, field))); } break; case FieldDescriptor::CPPTYPE_UINT64: if (repeated) { for (size_t i = 0; i != array_size; ++i) { uint64_t value = ref->GetRepeatedUInt64(*msg, field, i); rapidjson::Value v(value); json->PushBack(v, allocator); } } else { json = new rapidjson::Value(static_cast<uint64_t>(ref->GetUInt64(*msg, field))); } break; case FieldDescriptor::CPPTYPE_INT32: if (repeated) { for (size_t i = 0; i != array_size; ++i) { int32_t value = ref->GetRepeatedInt32(*msg, field, i); rapidjson::Value v(value); json->PushBack(v, allocator); } } else { json = new rapidjson::Value(ref->GetInt32(*msg, field)); } break; case FieldDescriptor::CPPTYPE_UINT32: if (repeated) { for (size_t i = 0; i != array_size; ++i) { uint32_t value = ref->GetRepeatedUInt32(*msg, field, i); rapidjson::Value v(value); json->PushBack(v, allocator); } } else { json = new rapidjson::Value(ref->GetUInt32(*msg, field)); } break; case FieldDescriptor::CPPTYPE_BOOL: if (repeated) { for (size_t i = 0; i != array_size; ++i) { bool value = ref->GetRepeatedBool(*msg, field, i); rapidjson::Value v(value); json->PushBack(v, allocator); } } else { json = new rapidjson::Value(ref->GetBool(*msg, field)); } break; case FieldDescriptor::CPPTYPE_STRING: { bool is_binary = field->type() == FieldDescriptor::TYPE_BYTES; if (repeated) { for (size_t i = 0; i != array_size; ++i) { std::string value = ref->GetRepeatedString(*msg, field, i); if (is_binary) { value = b64_encode(value); } rapidjson::Value v(value.c_str(), static_cast<rapidjson::SizeType>(value.size()), allocator); json->PushBack(v, allocator); } } else { std::string value = ref->GetString(*msg, field); if (is_binary) { value = b64_encode(value); } json = new rapidjson::Value(value.c_str(), value.size(), allocator); } break; } case FieldDescriptor::CPPTYPE_MESSAGE: if (repeated) { for (size_t i = 0; i != array_size; ++i) { const Message *value = &(ref->GetRepeatedMessage(*msg, field, i)); rapidjson::Value* v = parse_msg(value, allocator); json->PushBack(*v, allocator); delete v; } } else { const Message *value = &(ref->GetMessage(*msg, field)); json = parse_msg(value, allocator); } break; case FieldDescriptor::CPPTYPE_ENUM: if (repeated) { for (size_t i = 0; i != array_size; ++i) { const EnumValueDescriptor* value = ref->GetRepeatedEnum(*msg, field, i); rapidjson::Value v(value->number()); json->PushBack(v, allocator); } } else { json = new rapidjson::Value(ref->GetEnum(*msg, field)->number()); } break; default: break; } return json; }
WV_CencSingleSampleDecrypter::WV_CencSingleSampleDecrypter(std::string licenseURL, const uint8_t *pssh, size_t pssh_size) : AP4_CencSingleSampleDecrypter(0) , wv_adapter(0) , max_subsample_count_(0) , subsample_buffer_(0) { uint8_t buf[1024]; if (pssh_size > 256) { Log(SSD_HOST::LL_ERROR, "Init_data with length: %u seems not to be cenc init data!", pssh_size); return; } std::string strPath = host->GetDecrypterPath(); if (strPath.empty()) { Log(SSD_HOST::LL_ERROR, "Absolute path to widevine in settings expected"); return; } strPath += WIDEVINECDMFILENAME; wv_adapter = new media::CdmAdapter("com.widevine.alpha", strPath.c_str(), media::CdmConfig()); unsigned int buf_size = 32 + pssh_size; if (!wv_adapter->valid()) { Log(SSD_HOST::LL_ERROR, "Unable to load widevine shared library (%s)", strPath.c_str()); goto FAILURE; } // This will request a new session and initializes session_id and message members in cdm_adapter. // message will be used to create a license request in the step after CreateSession call. // Initialization data is the widevine cdm pssh code in google proto style found in mpd schemeIdUri static uint8_t proto[] = { 0x00, 0x00, 0x00, 0x63, 0x70, 0x73, 0x73, 0x68, 0x00, 0x00, 0x00, 0x00, 0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6, 0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc, 0xd5, 0x1d, 0x21, 0xed, 0x00, 0x00, 0x00, 0x43 }; memcpy(buf, proto, sizeof(proto)); memcpy(&buf[32], pssh, pssh_size); wv_adapter->CreateSessionAndGenerateRequest(0, cdm::SessionType::kTemporary, cdm::InitDataType::kCenc, buf, buf_size); if (wv_adapter->SessionValid()) { std::string license, challenge(b64_encode(wv_adapter->GetMessage(), wv_adapter->GetMessageSize(), true)); challenge = "widevine2Challenge=" + challenge; challenge += "&includeHdcpTestKeyInLicense=true"; // open the file void* file = host->CURLCreate(licenseURL.c_str()); host->CURLAddOption(file, SSD_HOST::OPTION_PROTOCOL, "acceptencoding", "gzip"); host->CURLAddOption(file, SSD_HOST::OPTION_PROTOCOL, "seekable", "0"); host->CURLAddOption(file, SSD_HOST::OPTION_HEADER, "Content-Type", "application/x-www-form-urlencoded"); size_t nbRead; std::string::size_type licStartPos, licEndPos; if (!host->CURLOpen(file, SSD_HOST::FILE_POST)) { Log(SSD_HOST::LL_ERROR, "Failed to open CURL file"); goto FAILURE; } if (size_t sz = host->WriteFile(file, challenge.c_str(), challenge.size()) != 200) { Log(SSD_HOST::LL_ERROR, "License server returned failure (%d)", static_cast<int>(sz)); host->CloseFile(file); goto FAILURE; } // read the file while ((nbRead = host->ReadFile(file, buf, 1024)) > 0) license += std::string((const char*)buf,nbRead); host->CloseFile(file); if (nbRead != 0) { Log(SSD_HOST::LL_ERROR, "Could not read full license response"); goto FAILURE; } licStartPos = license.find("\"license\":\""); if (licStartPos == std::string::npos) { Log(SSD_HOST::LL_ERROR, "License start position not found"); goto FAILURE; } licStartPos += 11; licEndPos = license.find("\",", licStartPos); if (licEndPos == std::string::npos) { Log(SSD_HOST::LL_ERROR, "License end position not found"); goto FAILURE; } buf_size = 1024; b64_decode(license.c_str() + licStartPos, licEndPos - licStartPos, buf, buf_size); wv_adapter->UpdateSession(buf, buf_size); if (!wv_adapter->KeyIdValid()) { Log(SSD_HOST::LL_ERROR, "License update not successful"); goto FAILURE; } // forbit auto delete for this object SetParentIsOwner(false); return; } FAILURE: delete wv_adapter; wv_adapter = 0; }
/* Prep and encrypt using gpgme */ static int gpg_encrypt(fko_ctx_t ctx, const char *enc_key) { int res; char *plain; int pt_len, zero_free_rv = FKO_SUCCESS; char *b64cipher; unsigned char *cipher = NULL; size_t cipher_len; char *empty_key = ""; if (! is_valid_encoded_msg_len(ctx->encoded_msg_len)) return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MESSAGE_VALIDFAIL); switch(ctx->digest_len) { case MD5_B64_LEN: break; case SHA1_B64_LEN: break; case SHA256_B64_LEN: break; case SHA384_B64_LEN: break; case SHA512_B64_LEN: break; default: return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_DIGEST_VALIDFAIL); } /* First make sure we have a recipient key set. */ if(ctx->gpg_recipient == NULL) return(FKO_ERROR_MISSING_GPG_KEY_DATA); pt_len = ctx->encoded_msg_len + ctx->digest_len + 2; /* Make a bucket big enough to hold the enc msg + digest (plaintext) * and populate it appropriately. */ plain = malloc(ctx->encoded_msg_len + ctx->digest_len + 2); if(plain == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); pt_len = snprintf(plain, pt_len+1, "%s:%s", ctx->encoded_msg, ctx->digest); if(! is_valid_pt_msg_len(pt_len)) { if(zero_free(plain, pt_len) == FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MSGLEN_VALIDFAIL); else return(FKO_ERROR_ZERO_OUT_DATA); } if (enc_key != NULL) { res = gpgme_encrypt(ctx, (unsigned char*)plain, pt_len, enc_key, &cipher, &cipher_len ); } else { res = gpgme_encrypt(ctx, (unsigned char*)plain, pt_len, empty_key, &cipher, &cipher_len ); } /* --DSS XXX: Better parsing of what went wrong would be nice :) */ if(res != FKO_SUCCESS) { zero_free_rv = zero_free(plain, pt_len); if(cipher != NULL) if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free_rv == FKO_SUCCESS) return(res); else return(zero_free_rv); } /* Now make a bucket for the base64-encoded version and populate it. */ b64cipher = malloc(((cipher_len / 3) * 4) + 8); if(b64cipher == NULL) { if(zero_free(plain, pt_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(cipher != NULL) if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free_rv == FKO_SUCCESS) return(FKO_ERROR_MEMORY_ALLOCATION); else return(zero_free_rv); } b64_encode(cipher, b64cipher, cipher_len); strip_b64_eq(b64cipher); if(ctx->encrypted_msg != NULL) zero_free_rv = zero_free(ctx->encrypted_msg, strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE)); ctx->encrypted_msg = strdup(b64cipher); ctx->encrypted_msg_len = strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE); /* Clean-up */ if(zero_free(plain, pt_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(zero_free(b64cipher, strnlen(b64cipher, MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS) zero_free_rv = FKO_ERROR_ZERO_OUT_DATA; if(ctx->encrypted_msg == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); if(! is_valid_encoded_msg_len(ctx->encrypted_msg_len)) return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_RESULT_MSGLEN_VALIDFAIL); return(zero_free_rv); }
int fko_set_spa_hmac(fko_ctx_t ctx, const char * const hmac_key, const int hmac_key_len) { unsigned char hmac[SHA512_DIGEST_STR_LEN] = {0}; char *hmac_base64 = NULL; int hmac_digest_str_len = 0; int hmac_digest_len = 0; /* Must be initialized */ if(!CTX_INITIALIZED(ctx)) return(FKO_ERROR_CTX_NOT_INITIALIZED); if(hmac_key_len > MAX_DIGEST_BLOCK_LEN) return(FKO_ERROR_INVALID_HMAC_KEY_LEN); if(ctx->hmac_type == FKO_HMAC_MD5) { hmac_md5(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = MD5_DIGEST_LEN; hmac_digest_str_len = MD5_DIGEST_STR_LEN; } else if(ctx->hmac_type == FKO_HMAC_SHA1) { hmac_sha1(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = SHA1_DIGEST_LEN; hmac_digest_str_len = SHA1_DIGEST_STR_LEN; } else if(ctx->hmac_type == FKO_HMAC_SHA256) { hmac_sha256(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = SHA256_DIGEST_LEN; hmac_digest_str_len = SHA256_DIGEST_STR_LEN; } else if(ctx->hmac_type == FKO_HMAC_SHA384) { hmac_sha384(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = SHA384_DIGEST_LEN; hmac_digest_str_len = SHA384_DIGEST_STR_LEN; } else if(ctx->hmac_type == FKO_HMAC_SHA512) { hmac_sha512(ctx->encrypted_msg, ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len); hmac_digest_len = SHA512_DIGEST_LEN; hmac_digest_str_len = SHA512_DIGEST_STR_LEN; } hmac_base64 = calloc(1, MD_HEX_SIZE(hmac_digest_len)+1); if (hmac_base64 == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); b64_encode(hmac, hmac_base64, hmac_digest_len); strip_b64_eq(hmac_base64); if(ctx->msg_hmac != NULL) free(ctx->msg_hmac); ctx->msg_hmac = strdup(hmac_base64); ctx->msg_hmac_len = strnlen(ctx->msg_hmac, hmac_digest_str_len); free(hmac_base64); switch(ctx->msg_hmac_len) { case MD5_B64_LEN: break; case SHA1_B64_LEN: break; case SHA256_B64_LEN: break; case SHA384_B64_LEN: break; case SHA512_B64_LEN: break; default: return(FKO_ERROR_INVALID_DATA); } return FKO_SUCCESS; }
/* Provide an FKO wrapper around base64 encode/decode functions */ int fko_base64_encode(unsigned char * const in, char * const out, int in_len) { return b64_encode(in, out, in_len); }