Illegal SNI hostname received - rust

I am using tokio rustls and I am getting Illegal SNI hostname received [49, 48, 46, 48, 46, 48, 46, 52] when hooking up a server to a legacy system.
This is my configuration:
let tls_cfg = {
// Load public certificate.
let server_cert = X509::stack_from_pem(server_cert.as_bytes()).unwrap();
let mut server_certs: Vec<Certificate> = Vec::new();
for x509 in server_cert {
let certificate = tokio_rustls::rustls::Certificate(x509.to_der().unwrap());
server_certs.push(certificate);
}
// Load private key.
let server_key = pem_parser::pem_to_der(server_key);
let server_key = tokio_rustls::rustls::PrivateKey(server_key);
// Do not use client certificate authentication.
let mut cfg = ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(server_certs, server_key)
.unwrap();
// Configure ALPN to accept HTTP/2, HTTP/1.1 in that order.
//cfg.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
sync::Arc::new(cfg)
};
let acceptor = tokio_rustls::TlsAcceptor::from(tls_cfg);
let client_stream = acceptor.accept_with(client_stream, session).await.unwrap();
Is there a way to ignore that illegal SNI message since I cannot change the code the generates it?

Related

How to return contents as a file download in Axum?

I have a Rust application that is acting as a proxy. From the user perspective there is a web UI front end. This contains a button that when invoked will trigger a GET request to the Rust application. This in turn calls an external endpoint that returns the CSV file.
What I want is have the file download to the browser when the user clicks the button. Right now, the contents of the CSV file are returned to the browser rather than the file itself.
use std::net::SocketAddr;
use axum::{Router, Server};
use axum::extract::Json;
use axum::routing::get;
pub async fn downloadfile() -> Result<Json<String>, ApiError> {
let filename = ...;
let endpoint = "http://127.0.0.1:6101/api/CSV/DownloadFile";
let path = format!("{}?filename={}", endpoint, filename);
let response = reqwest::get(path).await?;
let content = response.text().await?;
Ok(Json(content))
}
pub async fn serve(listen_addr: SocketAddr) {
let app = Router::new()
.route("/downloadfile", get(downloadfile));
Server::bind(&listen_addr)
.serve(app.into_make_service())
.await
.unwrap();
}
I understand the reason I'm getting the contents is because I'm returning the content string as JSON. This makes sense. However, what would I need to change to return the file itself so the browser downloads it directly for the user?
I've managed to resolve it and now returns the CSV as a file. Here's the function that works:
use axum::response::Headers;
use http::header::{self, HeaderName};
pub async fn downloadfile() -> Result<(Headers<[(HeaderName, &'static str); 2]>, String), ApiError> {
let filename = ...;
let endpoint = "http://127.0.0.1:6101/api/CSV/DownloadFile";
let path = format!("{}?filename={}", endpoint, filename);
let response = reqwest::get(path).await?;
let content = response.text().await?;
let headers = Headers([
(header::CONTENT_TYPE, "text/csv; charset=utf-8"),
(header::CONTENT_DISPOSITION, "attachment; filename=\"data.csv\""),
]);
Ok((headers, content))
}
I'm still struggling with being able to set a dynamic file name, but that for another question.

Solana transaction , unknown signer

I am trying to buy NFT from Magic Eden Solana with node js/typescript script,
at first I used solana CLI to get the keypair by using the command below
cat .../.config/solana/id.json
typescript :
let Array_key = [98, 90, 131, ...]; ```got it using solana cli from .../.config/solana/id.json```
let secret = Uint8Array.from(Array_key)
let signers = Keypair.fromSecretKey(Uint8Array.from(secrete))
const connection = new Connection("https://api.mainnet-beta.solana.com",'confirmed');
let publickey = new PublicKey("2Eod3hjZBJZzGYSJVrVtRC3UMZeonZYfUScmAy1tjD5c");```Wallet address```
let allocateTransaction = new Transaction({
feePayer: publickey,
});
const databuf = Buffer.from(parsed_buy_response['tx']['data'], "hex");```from https://api-mainnet.magiceden.io/v2/instructions/buy_now```
const keys: AccountMeta[] = await generateAccountList(MintAddress,publickey, connection);```function used from transaction.ts https://github.com/solanasoulja/sol-nft-sniper/blob/main/src/views/HomeView/transaction.ts```
allocateTransaction.add(new TransactionInstruction({
keys: keys,
programId: publickey,
data: databuf,
}));
await sendAndConfirmTransaction(connection, allocateTransaction, [signers]).then(resolve => {
console.log('transaction sent')
console.log(resolve)
}).catch(err => {
console.log('err at sending transaction')
console.log(err)
})
and the output is Error: unknown signer xxxxxxxxxxxxxxx,
noting that my wallet address is different than the signer, I don't know why I am getting a different signer.
I tried different method by generating the keypair using bip39 method as shown below:
async getKeyPair(mnemomic) {
const seed = bip39.mnemonicToSeedSync(mnemomic).slice(0, 32);
console.log(seed)
// let _KeyPairseed = await web3.PublicKey.createWithSeed(publicKey, seed, publicKey)
// console.log(_KeyPairseed)
const keypair = Keypair.fromSeed(seed);
console.log(keypair)
return keypair;
};
I get different error => verification error
not sure if I am missing a step.
If someone else is going through this problem, here is the answer. Make sure the wallet is written Anchor.toml and this same wallet should match the wallet in your test file.

Is it possible to have different result for eth tx signing methods? What is the solution in order to sign txs without eth node rpc connection?

I used to run an eth node and sign the txs using web3 library.
//tx = {from, to, data, ...}
const privateKey = 'XXX' (without 0x prefix);
let web3SignedTx = await web3.eth.accounts.signTransaction(tx, privateKey);
I decided to stop running Eth node and to sign txs with a different way, using ethereumjs-tx.
const Eth_Tx = require('ethereumjs-tx').Transaction;
const privateKeyBuffer = Buffer.from(privateKey, 'hex');
let txObj = new Eth_Tx(tx);
txObj.sign(privateKeyBuffer);
let serializedTx = txObj.serialize();
let rawTransaction = '0x' + serializedTx.toString('hex');
The problem is that the above method does not produce the same rawTransaction output as the web3 method. (web3SignedTx.rawTransaction !== rawTransaction)
It cannot be broadcasted as well.
I dont know what i am missing here, can you provide any suggestion/solution for the above problem or for a method that i can sign txs without the need of eth-node or any rpc connection?

error trying to connect: the certificate was not trusted

I am running docker container which contains REST API with tls enable, For which I am passing self signed .pem certificate and I am using reqwest crate to call the REST API. If tls is disable with container it works well. But when I run container with certificate, reqwest API call giving me error as mention below.Even after passing the same certificate from self-signed also giving me error.
error trying to connect: The certificate was not trusted."
reqwest = { version = "0.11.4", features = ["blocking", "json","native-tls"] }
async fn call_api<T: serde::Serialize>(
&self,
builder: ClientBuilder,
params: &T,
request_url: &str,
) -> Result<serde_json::Value> {
let mut headers = header::HeaderMap::new();
headers.insert(
header::AUTHORIZATION,
header::HeaderValue::from_str(self.token.as_str()).unwrap(),
);
headers.insert(
header::CONTENT_TYPE,
header::HeaderValue::from_static("application/json"),
);
// read a local binary pem encoded certificate
let pem = std::fs::read("./cert.pem").unwrap();
let cert = reqwest::Certificate::from_pem(&pem)?;
let client = builder
.add_root_certificate(cert)
.default_headers(headers)
.build()?;
let response_json: serde_json::Value = client
.get(request_url)
.json(params)
.send()
.await?
.json()
.await?;
Ok(response_json)
}

AES 256 GCM encryption decryption does not work on android device

I'm working on a react-native project and trying to encrypt and decrypt the photo by crypto and using aes-256-gcm algorithm. This code works well on simulator both android and ios, these is no issue on device when I'm debugging as well, but as soon as I stop Remote JS Debugging on android device, this error'll appear: unsupported state or unable to authenticate data.
I'm completely confuse and I don't know how I can fix this issue.
I should mention that this code'll work correctly for small data and string, only there is problem with large file.
Here is my code:
key = crypto.randomBytes(32);
static encryptFile = inData => {
let iv = Buffer.from(crypto.randomBytes(16));
let cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(inData, "binary", "hex");
encrypted += cipher.final("hex");
let cipherTag = cipher.getAuthTag();
encrypted += "," + iv.toString("hex") + "," + cipherTag.toString("hex");
return encrypted;
};
static decryptFile = inEncData => {
let encParts = inEncData.split(",");
let currentIV = Buffer.from(encParts[1], "hex");
let currentTag = Buffer.from(encParts[2], "hex");
let decipher = crypto.createDecipheriv(algorithm, key, currentIV);
decipher.setAuthTag(currentTag);
let decrypted = decipher.update(encParts[0], "hex");
let decryptedFinal = decipher.final();
Buffer.concat([decrypted, decryptedFinal]);
return decrypted;
};
I read image file by rn-fetch-blob and pass it to encryptFile method:
let res = await RNFetchBlob.fs.readFile(filePath, "ascii");
let enc = convertor.encryptFile(res);
let dec = convertor.decryptFile(enc);
And the error occurs on decryptFile method.
Just add utf-8 with hex encoding parameters shown below:
let encrypted = cipher.update(inData, "utf8", "hex");
encrypted += cipher.final("hex");
let decrypted = decipher.update(encParts[0], "hex","utf8");
let decryptedFinal = decipher.final('utf8');

Resources