/* * Init JNI fields, fetch the key stored by Android or generate a new one */ static void AndroidInit(vlc_keystore *p_keystore) { JNIEnv *p_env = GET_ENV(); if (p_env == NULL) return; if (InitJni(p_keystore, p_env) != VLC_SUCCESS) return; jobject jkeystore = NULL, jentry = NULL, jkey = NULL; jstring jstringAlias = NULL, jstringProvider = NULL; jstringAlias = NEW_STR("LibVLCAndroid"); if (CHECK_EXCEPTION()) goto end; jstringProvider = NEW_STR("AndroidKeyStore"); if (CHECK_EXCEPTION()) goto end; jkeystore = CALL_STATICOBJ(KeyStore, KeyStore.getInstance, jstringProvider); if (CHECK_EXCEPTION()) goto end; CALL_VOID(jkeystore, KeyStore.load, NULL); if (CHECK_EXCEPTION()) goto end; jentry = CALL_OBJ(jkeystore, KeyStore.getEntry, jstringAlias, NULL); if (CHECK_EXCEPTION()) goto end; if (jentry != NULL) { jkey = CALL_OBJ(jentry, KeyStore.SecretKeyEntry.getSecretKey); if (CHECK_EXCEPTION()) goto end; } else { jkey = GenerateKey(p_keystore, p_env, jstringAlias, jstringProvider); if (jkey == NULL) goto end; } s_jkey = NEW_GREF(jkey); end: if (jstringAlias != NULL) DEL_LREF(jstringAlias); if (jstringProvider != NULL) DEL_LREF(jstringProvider); if (jkeystore != NULL) DEL_LREF(jkeystore); if (jentry != NULL) DEL_LREF(jentry); if (jkey != NULL) DEL_LREF(jkey); }
static size_t AndroidDecrypt(vlc_keystore *p_keystore, void *p_ctx, const uint8_t *p_src, size_t i_src_len, uint8_t **pp_dst) { (void) p_ctx; JNIEnv *p_env = GET_ENV(); if (p_env == NULL) return 0; jobject jivArray = NULL, jiv = NULL, jcipher = NULL; jcipher = CALL_STATICOBJ(Cipher, Cipher.getInstance, fields.VLC_CIPHER); if (CHECK_EXCEPTION()) return 0; /* Get the IV located at the beginning of the secret */ size_t i_dst_len = 0; uint32_t i_iv_len; if (i_src_len < sizeof(uint32_t)) goto end; memcpy(&i_iv_len, p_src, sizeof(uint32_t)); if (i_iv_len == 0 || i_src_len < (sizeof(uint32_t) + i_iv_len)) goto end; jivArray = (*p_env)->NewByteArray(p_env, i_iv_len); if (CHECK_EXCEPTION()) goto end; (*p_env)->SetByteArrayRegion(p_env, jivArray, 0, i_iv_len, (jbyte *)(p_src + sizeof(uint32_t)) ); jiv = NEW_OBJECT(IvParameterSpec, jivArray); if (CHECK_EXCEPTION()) goto end; /* Use the IV to initialize the decrypt Cipher */ CALL_VOID(jcipher, Cipher.init, fields.Cipher.DECRYPT_MODE, s_jkey, jiv); if (CHECK_EXCEPTION()) goto end; i_dst_len = Process(p_keystore, p_env, jcipher, p_src + sizeof(uint32_t) + i_iv_len, i_src_len - sizeof(uint32_t) - i_iv_len, NULL, 0, pp_dst); end: DEL_LREF(jcipher); if (jivArray != NULL) DEL_LREF(jivArray); if (jiv != NULL) DEL_LREF(jiv); return i_dst_len; }
void internal_print_env(FILE* fp, CELL env) { fputc('[', fp); while(ENVP(env)) { ENV* p = GET_ENV(env); int i; fputc('{', fp); for(i = 0; i < p->count; ++i) { if (i > 0) fprintf(fp, ", "); fprintf(fp, "#%d=", p->depth + i); internal_generic_output(fp, p->cells[i], 1, 0); } fputc('}', fp); env = p->next; if (ENVP(env)) fputc(';', fp); } fputc(']', fp); }
static size_t AndroidEncrypt(vlc_keystore *p_keystore, void *p_ctx, const uint8_t *p_src, size_t i_src_len, uint8_t **pp_dst) { (void) p_ctx; JNIEnv *p_env = GET_ENV(); if (p_env == NULL) return 0; jobject jcipher = NULL; jcipher = CALL_STATICOBJ(Cipher, Cipher.getInstance, fields.VLC_CIPHER); if (CHECK_EXCEPTION()) return 0; size_t i_dst_len = 0; CALL_VOID(jcipher, Cipher.init, fields.Cipher.ENCRYPT_MODE, s_jkey, NULL); if (CHECK_EXCEPTION()) goto end; /* Get the IV (Initialization Vector) initialized by Android that will be * used to decrypt this secret. This IV will be stored with the encrypted * secret */ jarray jivArray = (jarray) CALL_OBJ(jcipher, Cipher.getIV); if (jivArray == NULL) goto end; jsize i_iv_len = (*p_env)->GetArrayLength(p_env, jivArray); if (i_iv_len == 0) goto end; jbyte *p_iv_bytes = (*p_env)->GetByteArrayElements(p_env, jivArray, 0); i_dst_len = Process(p_keystore, p_env, jcipher, p_src, i_src_len, (const uint8_t *)p_iv_bytes, i_iv_len, pp_dst); (*p_env)->ReleaseByteArrayElements(p_env, jivArray, p_iv_bytes, 0); DEL_LREF(jivArray); end: DEL_LREF(jcipher); return i_dst_len; }
void internal_generic_output(FILE* fp, CELL cell, int strict, int tab) { switch(GET_TYPE(cell)) { case T_VOID: fputs("#<void>", fp); break; case T_NULL: fputs("()", fp); break; case T_UNDEFINED: fputs("#<undefined>", fp); break; case T_EMPTY: fputs("#<empty>", fp); break; case T_BOOL: fputs(GET_BOOL(cell) ? "#t" : "#f", fp); break; case T_CHAR: { CHAR ch = GET_CHAR(cell); if (strict) { switch(ch) { case ' ': fputs("#\\space", fp); break; case 0: fputs("#\\nul", fp); break; case 27: fputs("#\\escape", fp); break; case 127: fputs("#\\rubout", fp); break; case '\a': fputs("#\\alarm", fp); break; case '\b': fputs("#\\backspace", fp); break; case '\f': fputs("#\\page", fp); break; case '\n': fputs("#\\newline", fp); break; case '\r': fputs("#\\return", fp); break; case '\t': fputs("#\\tab", fp); break; case '\v': fputs("#\\vtab", fp); break; default: fprintf(fp, "#\\%c", ch); break; } } else { fputc(ch, fp); } } break; case T_INT: fprintf(fp, "%d", GET_INT(cell)); break; case T_BIGINT: fprintf(fp, "%lld", GET_BIGINT(cell)); break; case T_FLOAT: fprintf(fp, "%f", GET_FLOAT(cell)); break; case T_STRING: { STRING* p = GET_STRING(cell); size_t len = p->len; char* data = p->data; if (strict) { // FIXME -- make this more efficient, and escape other special chars? fputc('"', fp); while(len--) { char ch = *data++; if (ch == '"' || ch == '\\') { fputc('\\', fp); } fputc(ch, fp); } fputc('"', fp); } else { fwrite(data, 1, len, fp); } } break; case T_NAME: { NAME* p = GET_NAME(cell); if (p->gensym) { fprintf(fp, "#_%d", p->gensym); } else { fwrite(GET_NAME(cell)->data, 1, GET_NAME(cell)->len, fp); } } break; case T_KEYWORD: { KEYWORD* p = GET_KEYWORD(cell); fwrite(p->data, 1, p->len, fp); fputc(':', fp); } break; case T_SLOT: fprintf(fp, "#<slot:%d>", GET_SLOT(cell)); break; // FIXME - arbitrary recursion case T_CONS: fputc('(', fp); if (tab) ++tab; int did = 0; while(1) { int pair = CONSP(CAR(cell)); if (!did && tab && pair && !CONSP(CAR(CAR(cell)))) { fprintf(fp, "\n%*s", (tab-1)*2, ""); } internal_generic_output(fp, CAR(cell), strict, tab); cell = CDR(cell); if (NULLP(cell)) { break; } did = (tab && pair); if (did) { fprintf(fp, "\n%*s", (tab-1)*2, ""); } else fputc(' ', fp); if (!CONSP(cell)) { fputs(". ", fp); internal_generic_output(fp, cell, strict, tab); break; } } fputc(')', fp); break; // FIXME - arbitrary recursion case T_VECTOR: { VECTOR *vec = GET_VECTOR(cell); fputs("#(", fp); if (vec->len > 0) { int i = 0; internal_generic_output(fp, vec->data[i++], strict, tab); while(i < vec->len) { fputc(' ', fp); internal_generic_output(fp, vec->data[i++], strict, tab); } } fputc(')', fp); break; } case T_FUNC: fprintf(fp, "#<primitive:%s>", GET_FUNC(cell)->name); break; case T_COMPILED_LAMBDA: fprintf(fp, "#<compiled-lambda:0x%08x>", AS_LITERAL(cell)); break; { if (tab) ++tab; COMPILED_LAMBDA *l = GET_COMPILED_LAMBDA(cell); fprintf(fp, "#<%s %d%s:%d/%d", l->is_macro ? "macro" : "lambda", l->argc, l->rest ? "+" : "", l->depth, l->max_slot); if (tab) { fprintf(fp, "\n%*s", (tab-1)*2, ""); } else { fputc(' ', fp); } internal_generic_output(fp, l->body, strict, tab); fputc('>', fp); } break; case T_CLOSURE: fprintf(fp, "#<closure:0x%08x>", AS_LITERAL(cell)); break; { if (tab) ++tab; CLOSURE *c = GET_CLOSURE(cell); fprintf(fp, "#<closure "); if (tab) { fprintf(fp, "\n%*s", (tab-1)*2, ""); } internal_print_env(fp, c->env); if (tab) { fprintf(fp, "\n%*s", (tab-1)*2, ""); } fputc(' ', fp); internal_generic_output(fp, c->compiled_lambda, strict, tab); fputc('>', fp); } break; case T_EXCEPTION: fputs("#<exception:", fp); fwrite(GET_EXCEPTION(cell)->data, 1, GET_EXCEPTION(cell)->len, fp); fputc('>', fp); break; case T_REIFIED_CONTINUATION: fprintf(fp, "#<continuation:0x%08x>", (int)GET_REIFIED_CONTINUATION(cell)->cont); break; case T_STACK_FRAME: { STACK_FRAME* p = GET_STACK_FRAME(cell); fputs("#<stack-frame [", fp); int i; for(i = 0; i < p->len; ++i) { if (i) fputc(' ', fp); fprintf(fp, "0x%08x", (int)p->cells[i]); } fputs("]>", fp); } break; case T_ENV: fprintf(fp, "#<env:count=%d>", GET_ENV(cell)->count); break; case T_RELOC: fprintf(fp, "#<reloc:0x%08x>", (int)GET_RELOC(cell)); break; case T_PORT: fprintf(fp, "#<port:%s>", GET_PORT(cell)->data); break; case T_DB_CONNECTION: fprintf(fp, "#<db-connection>"); break; case T_DB_RESULT: fprintf(fp, "#<db-result>"); break; case T_RECORD: fprintf(fp, "#<record>"); break; default: fprintf(fp, "#<%s-%02x:%08x>", IS_LITERAL(cell) ? "literal" : "pointer", GET_TYPE(cell), AS_LITERAL(cell) ); break; } }