int main () { char *B64Text = "HUIfTQsPAh9PE048GmllH0kcDk4TAQsHThsBFkU2AB4BSWQgVB0dQzNTTmVSBgBHVBwNRU0HBAxTEjwMHghJGgkRTxRMIRpHKwAFHUdZEQQJAGQmB1MANxYGDBoXQR0BUlQwXwAgEwoFR0$"; char *buf = malloc(Base64decode_len(B64Text)); Base64decode(buf, B64Text); RepeatedXorAnalysis(buf, Base64decode_len(B64Text) - 1); }
int CACrypto::decodeBase64(const char* input, char* output, int outputBufferLength) { CCAssert(Base64decode_len(input) <= outputBufferLength, "CACrypto::decodeBase64() - outputBufferLength too small"); return Base64decode(output, input); }
LUA_STRING Crypto::encodingBase64Lua(bool isDecoding, const char* input, int inputLength) { LuaStack* stack = LuaEngine::getInstance()->getLuaStack(); stack->clean(); int bufferSize = isDecoding ? Base64decode_len(input) : Base64encode_len(inputLength); char *buffer = bufferSize ? (char*)malloc(bufferSize) : NULL; int size = 0; if (buffer) { size = isDecoding ? Base64decode(buffer, input) : Base64encode(buffer, input, inputLength); } if (size) { stack->pushString(buffer, size); } else { stack->pushNil(); } if (buffer) { free(buffer); } return 1; }
fzBuffer Data::B64Decode(const char *input, fzUInt inLength) { FZ_ASSERT(input, "Input pointer cannot be NULL"); FZ_ASSERT(inLength > 0, "Input data length cannot be 0."); //should be enough to store 6-bit buffers in 8-bit buffers fzUInt outputSize = Base64decode_len(input); char *output = new(std::nothrow) char[outputSize]; if( output ) { Base64decode(output, input); return fzBuffer(output, outputSize); }else{ FZLOGERROR("Base64: error allocating memory."); return fzBuffer::empty(); } }
extern "C" int Base64DecodedLength(const char* base64Src) { return Base64decode_len(base64Src); }
int CACrypto::decodeBase64Len(const char* input) { return Base64decode_len(input); }
void nc_otoc_start(nc_opts *opts, int pair_raw_sock) { int shell_fd_sock; int pair_fd_sock; fd_set readfds; int maxfds; char time_str[NOW_STR_LEN]; enum {init, none, text_sent, text_received, pkey_sent, pkey_received} last_action = init; shell_fd_sock = fileno(stdin); pair_fd_sock = nc_utils_get_rec_sockfd(pair_raw_sock); maxfds = pair_fd_sock + 1; /* --- start of sending public key --- */ if(opts->secure) { char *msg = NULL; char *msg_type = OTOC_MTYPE_PKEY; char *msg_body = NULL; /* --- start of encoding public key --- */ const char *plain_pkey = (const char*) my_publickey; int plain_pkey_len = crypto_box_PUBLICKEYBYTES; char encoded_pkey[Base64encode_len(plain_pkey_len)]; Base64encode(encoded_pkey, plain_pkey, plain_pkey_len); nc_log_writef("debug", "encode my public key: %s", encoded_pkey); /* --- end of encoding public key --- */ msg_body = encoded_pkey; nc_json_make_otoc_msg(&msg_type, &msg_body, plain_pkey_len, &msg); nn_send(pair_raw_sock, msg, strlen(msg), 0); nc_log_writef("debug", "one to one chat sent public key: %s", msg); last_action = pkey_sent; } /* --- end of sending public key --- */ /* --- start of shel command registration --- */ nc_otoc_register_cmd("/help", func_cmd_help); nc_otoc_register_cmd("/leave", func_cmd_leave); /* --- end of shell commmand registration --- */ for(;;) { switch(last_action) { case init: case pkey_sent: fprintf(stdout, ">> Entering (room code %d) ...\n", pair_raw_sock); fprintf(stdout, ">>> "); fflush(stdout); break; case text_received: fprintf(stdout, ">>> "); fflush(stdout); break; case text_sent: fprintf(stdout, ">>> "); fflush(stdout); break; case none: fprintf(stdout, ">>> "); fflush(stdout); break; case pkey_received: break; } FD_ZERO(&readfds); FD_SET(pair_fd_sock, &readfds); FD_SET(shell_fd_sock, &readfds); select(maxfds, &readfds, NULL, NULL, NULL); if(FD_ISSET(shell_fd_sock, &readfds)) { char *buf = NULL; size_t buf_sz = 1024; int i; nc_utils_now_str(time_str); getline(&buf, &buf_sz, stdin); if(buf[0] == '\n') { last_action = none; } else if(buf[0] == '/') { nc_utils_del_new_line(buf); for(i = 0; i < cmd_current_code; i++) { if(strstr(buf, cmds[i].name)) { if(cmds[i].func(buf) < 0) { return; } break; } } last_action = none; } else { if(opts->secure) { /* --- make ciphermsg with key pairs --- */ int ciphermsg_len = crypto_box_MACBYTES + strlen(buf); unsigned char nonce[crypto_box_NONCEBYTES]; unsigned char ciphermsg[ciphermsg_len]; /* @TODO: use random nonce */ //randombytes_buf(nonce, sizeof nonce); memset(nonce, '\0', sizeof nonce); crypto_box_easy(ciphermsg, (const unsigned char*) buf, strlen(buf), nonce, peers_publickey[pair_raw_sock], my_secretkey); /* --- make msg encoded with base64 --- */ const char *plain_ciphermsg = (const char*) ciphermsg; int plain_ciphermsg_len = ciphermsg_len; int encoded_ciphermsg_len = Base64encode_len(plain_ciphermsg_len); char encoded_ciphermsg[encoded_ciphermsg_len]; Base64encode(encoded_ciphermsg, plain_ciphermsg, plain_ciphermsg_len); nc_log_writef("debug", "encode ciphermsg: %s", encoded_ciphermsg); /* --- serialize msg with json --- */ char *msg = NULL; char *msg_type = OTOC_MTYPE_STXT; char *msg_body = NULL; msg_body = encoded_ciphermsg; nc_json_make_otoc_msg(&msg_type, &msg_body, strlen(buf), &msg); nc_log_writef("debug", "serialize encoded ciphermsg: %s", msg); /* --- send msg --- */ nn_send(pair_raw_sock, msg, strlen(msg), 0); } else { char *msg = NULL; char *msg_type = OTOC_MTYPE_RTXT; nc_json_make_otoc_msg(&msg_type, &buf, strlen(buf), &msg); nn_send(pair_raw_sock, msg, strlen(msg), 0); fprintf(stdout, "[%s] >>> %s", time_str, buf); fflush(stdout); nc_utils_del_new_line(buf); nc_log_writef("debug", "one to one chat sent: %s", buf); nc_utils_empty_string(buf); last_action = text_sent; } } } else if(FD_ISSET(pair_fd_sock, &readfds)) { char *buf = NULL; char *msg_body = NULL; char *msg_type = NULL; int original_msg_body_len; nn_recv(pair_raw_sock, &buf, NN_MSG, 0); nc_json_extract_otoc_msg(&buf, &msg_type, &original_msg_body_len, &msg_body); nc_utils_del_new_line(buf); nc_log_writef("debug", "one to one chat received: %s", msg_type); nn_freemsg(buf); if(strncmp(msg_type, OTOC_MTYPE_PKEY, OTOC_MTYPE_LEN) == 0) { /* public key message */ /* --- start of decoding public key --- */ int plain_pkey_len = Base64decode_len(msg_body); char plain_pkey[plain_pkey_len]; Base64decode(plain_pkey, (const char*) msg_body); strncpy(peers_publickey[pair_raw_sock], plain_pkey, crypto_box_PUBLICKEYBYTES); nc_log_writef("debug", "decoded peer's public key was stored."); /* --- end of decoding public key --- */ last_action = pkey_received; } else if(strncmp(msg_type, OTOC_MTYPE_RTXT, OTOC_MTYPE_LEN) == 0) { /* raw text message */ nc_utils_now_str(time_str); fprintf(stdout, "\r[%s] <<< %s", time_str, msg_body); fflush(stdout); last_action = text_received; } else if(strncmp(msg_type, OTOC_MTYPE_STXT, OTOC_MTYPE_LEN) == 0) { /* secure text message */ if(!opts->secure) { char *alert = "\r[%s] <<< { ... encrypted message ... }\n" "==========================================\n" "Your peer uses NanoChat undre secure mode.\n" "Use -s flag to see his encrypted messages.\n" "==========================================\n"; nc_utils_now_str(time_str); fprintf(stdout, alert, time_str); fflush(stdout); last_action = text_received; } else { /* --- decode secure msg body --- */ int plain_ciphermsg_len = Base64decode_len(msg_body); char plain_ciphermsg[plain_ciphermsg_len]; Base64decode(plain_ciphermsg, (const char*) msg_body); /* --- decrypt ciphermsg --- */ int decrypted_len = original_msg_body_len; int ciphermsg_len = crypto_box_MACBYTES + decrypted_len; unsigned char decrypted[decrypted_len]; unsigned char nonce[crypto_box_NONCEBYTES]; memset(nonce, '\0', sizeof nonce); crypto_box_open_easy(decrypted, plain_ciphermsg, ciphermsg_len, nonce, peers_publickey[pair_raw_sock], my_secretkey); /* --- show decrypted msg body --- */ decrypted[original_msg_body_len] = '\0'; nc_utils_now_str(time_str); fprintf(stdout, "\r[%s] <<< %s", time_str, decrypted); fflush(stdout); last_action = text_received; } } } } }
static bool CreateDictionaryFromXMLRecursive(char *data, int size, CFMutableDictionaryRef *dict, char *key) { if (size == 0) return true; xml_token tok; char *buf = data; int bytesleft = size, closeindex; bool bClosed, bAllocatedKey = false; while (bytesleft) { // skip whitespace if (isspace(buf[0])) { buf++; bytesleft--; continue; } bClosed = false; closeindex = -1; // get XML token if (!GetNextToken(&buf, &bytesleft, &tok, &bClosed)) { if (bAllocatedKey) free(key); return false; } // closed XML token? if (bClosed) { if (key == NULL) continue; if (*dict == NULL) { if (bAllocatedKey) free(key); return false; } CFBooleanRef value = NULL; if (!strcasecmp(tok.id, "true")) { value = kCFBooleanTrue; } else if (!strcasecmp(tok.id, "false")) { value = kCFBooleanFalse; } if (value != NULL) { CFStringRef cfkey = CFStringCreateWithCString(kCFAllocatorDefault, key, kCFStringEncodingUTF8); if (bAllocatedKey) { free(key); key = NULL; bAllocatedKey = false; } if (cfkey == NULL) { return false; } CFDictionaryAddValue(*dict, cfkey, value); } else if (bAllocatedKey) { free(key); key = NULL; bAllocatedKey = false; } continue; } // check for token types we know about if (!strcasecmp(tok.id, "key")) { if (bAllocatedKey) free(key); if (*dict == NULL) return false; closeindex = PIGetIndexOfClosingTag(buf, bytesleft, "key"); if (closeindex == -1) return false; key = (char*)malloc(closeindex+1); strncpy(key, buf, closeindex); key[closeindex] = 0; StripWhitespace(&key); #ifdef DEBUG printf("key = %s\n", key); #endif // empty keys are not allowed if (strlen(key) == 0) { free(key); return false; } bAllocatedKey = true; buf += closeindex + 6; bytesleft -= closeindex + 6; } else if (!strcasecmp(tok.id, "dict")) { if (key == NULL) { if (*dict != NULL) return false; closeindex = PIGetIndexOfClosingTag(buf, bytesleft, "dict"); if (closeindex == -1) { return false; } *dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (*dict == NULL) { return false; } if (!CreateDictionaryFromXMLRecursive(buf, closeindex, dict, NULL)) { CFRelease(*dict); return false; } return true; } else if (*dict != NULL) { closeindex = PIGetIndexOfClosingTag(buf, bytesleft, "dict"); if (closeindex == -1) { if (bAllocatedKey) free(key); return false; } CFMutableDictionaryRef dict2 = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (dict2 == NULL) { if (bAllocatedKey) free(key); return false; } if (!CreateDictionaryFromXMLRecursive(buf, closeindex, &dict2, NULL)) { if (bAllocatedKey) free(key); CFRelease(dict2); return false; } CFStringRef cfkey = CFStringCreateWithCString(kCFAllocatorDefault, key, kCFStringEncodingUTF8); if (bAllocatedKey) { free(key); key = NULL; bAllocatedKey = false; } if (cfkey == NULL) { CFRelease(dict2); return false; } CFDictionaryAddValue(*dict, cfkey, dict2); buf += closeindex + 7; bytesleft -= closeindex + 7; } else { if (bAllocatedKey) free(key); return false; } } else if (!strcasecmp(tok.id, "data")) { if ( (key == NULL) || (*dict == NULL) ) return false; closeindex = PIGetIndexOfClosingTag(buf, bytesleft, "data"); if (closeindex == -1) { if (bAllocatedKey) free(key); return false; } CFStringRef cfkey = CFStringCreateWithCString(kCFAllocatorDefault, key, kCFStringEncodingUTF8); if (bAllocatedKey) { free(key); key = NULL; bAllocatedKey = false; } if (cfkey == NULL) { return false; } char *value = (char*)malloc(closeindex+1); strncpy(value, buf, closeindex); value[closeindex] = 0; StripWhitespace(&value); if (strlen(value) > 0) { // Base64 decode the data int decodelen = Base64decode_len(value); if (decodelen > 0) { char *decodedval = (char*)malloc(decodelen); Base64decode(decodedval, value); free(value); value = decodedval; } } CFDataRef cfvalue = CFDataCreate(kCFAllocatorDefault, (const UInt8*)value, strlen(value)); free(value); if (cfvalue == NULL) { return false; } CFDictionaryAddValue(*dict, cfkey, cfvalue); buf += closeindex + 7; bytesleft -= closeindex + 7; } else if (!strcasecmp(tok.id, "string")) { if ( (key == NULL) || (*dict == NULL) ) return false; closeindex = PIGetIndexOfClosingTag(buf, bytesleft, "string"); if (closeindex == -1) { if (bAllocatedKey) free(key); return false; } CFStringRef cfkey = CFStringCreateWithCString(kCFAllocatorDefault, key, kCFStringEncodingUTF8); if (bAllocatedKey) { free(key); key = NULL; bAllocatedKey = false; } if (cfkey == NULL) { return false; } char *value = (char*)malloc(closeindex+1); strncpy(value, buf, closeindex); value[closeindex] = 0; StripWhitespace(&value); #ifdef DEBUG printf("string = %s\n", value); #endif CFStringRef cfvalue = CFStringCreateWithCString(kCFAllocatorDefault, value, kCFStringEncodingUTF8); free(value); if (cfvalue == NULL) { return false; } CFDictionaryAddValue(*dict, cfkey, cfvalue); buf += closeindex + 9; bytesleft -= closeindex + 9; } else if (!strcasecmp(tok.id, "?xml") || !strcasecmp(tok.id, "!DOCTYPE") || !strcasecmp(tok.id, "plist")) { // Ignore } else { // unknown token -- just skip it if (bAllocatedKey) { free(key); key = NULL; bAllocatedKey = false; } closeindex = PIGetIndexOfClosingTag(buf, bytesleft, tok.id); if (closeindex == -1) { return false; } buf += closeindex + strlen(tok.id) + 3; bytesleft -= closeindex + strlen(tok.id) + 3; } } if (bAllocatedKey) free(key); return true; }