/* * JS update 14.04.2024 * Doplneny vypis pre algoritmy ML-KEM a ML-DSA */ /* * JS update 29.02.2024 * Doplnene vypisy pre PQ algoritmy * Odstranene funkcie pre ARDUINO */ // // Log protocol progress // #include "tls_logger.h" #include // all terminal output redirected here void myprintf(char *s) { printf("%s",s); } // log debug string and info or octad // if string is not NULL, output info, with format in string // if O is not null, output octad in hex. void log(int logit,char *preamble,char *string,unsign32 info,octad *O) { if (logit>VERBOSITY) return; #if VERBOSITY>IO_NONE char w[16]; myprintf(preamble); if (O!=NULL) { char buff[LOG_OUTPUT_TRUNCATION+8]; bool res=OCT_output_hex(O,LOG_OUTPUT_TRUNCATION,buff); sprintf(w,"(%d) ",O->len); myprintf(w); myprintf(buff); if (!res) myprintf((char *)" (truncated)"); myprintf((char *)"\n"); return; } if (string!=NULL) { // if its bigger than 6 its not a format descriptor ??? if (strlen(string)>6) myprintf(string); else { sprintf(w,string,info); myprintf(w); } myprintf((char *)"\n"); return; } #endif } static void nameCipherSuite(int cipher_suite) { switch (cipher_suite) { case TLS_AES_128_GCM_SHA256: myprintf((char *)"TLS_AES_128_GCM_SHA256\n"); break; case TLS_AES_256_GCM_SHA384: myprintf((char *)"TLS_AES_256_GCM_SHA384\n"); break; case TLS_CHACHA20_POLY1305_SHA256: myprintf((char *)"TLS_CHACHA20_POLY1305_SHA256\n"); break; default: myprintf((char *)"Non-standard\n"); break; } } void logCipherSuite(int cipher_suite) { #if VERBOSITY >= IO_DEBUG log(IO_DEBUG,(char *)"Cipher Suite is ",NULL,0,NULL); nameCipherSuite(cipher_suite); #endif } // JS doplnene nazvy PQ algoritmov static void nameKeyExchange(int kex) { #if VERBOSITY >= IO_PROTOCOL switch (kex) { case X25519: myprintf((char *)"X25519\n"); break; case SECP256R1: myprintf((char *)"SECP256R1\n"); break; case SECP384R1: myprintf((char *)"SECP384R1\n"); break; case KYBER768: myprintf((char *)"KYBER768\n"); break; case KYBER512: myprintf((char *)"KYBER512\n"); break; case KYBER1024: myprintf((char *)"KYBER1024\n"); break; case MLKEM512: myprintf((char *)"MLKEM512\n"); break; case MLKEM768: myprintf((char *)"MLKEM768\n"); break; case MLKEM1024: myprintf((char *)"MLKEM1024\n"); break; case BIKEL1: myprintf((char *)"BIKEL1\n"); break; case BIKEL3: myprintf((char *)"BIKEL3\n"); break; case BIKEL5: myprintf((char *)"BIKEL5\n"); break; case HQC128: myprintf((char *)"HQC128\n"); break; case HQC192: myprintf((char *)"HQC192\n"); break; case HQC256: myprintf((char *)"HQC256\n"); break; case FRODO640AES: myprintf((char *)"FRODO640AES\n"); break; case FRODO640SHAKE: myprintf((char *)"FRODO640SHAKE\n"); break; case FRODO976AES: myprintf((char *)"FRODO976AES\n"); break; case FRODO976SHAKE: myprintf((char *)"FRODO976SHAKE\n"); break; case FRODO1344AES: myprintf((char *)"FRODO1344AES\n"); break; case FRODO1344SHAKE: myprintf((char *)"FRODO1344SHAKE\n"); break; case HYBRID_KX: myprintf((char *)"KYBER + X25519\n"); break; default: myprintf((char *)"Non-standard\n"); break; } #endif } void logKeyExchange(int kex) { log(IO_PROTOCOL,(char *)"Key Exchange Group is ",NULL,0,NULL); nameKeyExchange(kex); } // JS doplnene nazvy PQ algoritmov static void nameSigAlg(int sigAlg) { #if VERBOSITY >= IO_PROTOCOL switch (sigAlg) { case ECDSA_SECP256R1_SHA256: myprintf((char *)"ECDSA_SECP256R1_SHA256\n"); break; case RSA_PSS_RSAE_SHA256: myprintf((char *)"RSA_PSS_RSAE_SHA256\n"); break; case RSA_PKCS1_SHA256: myprintf((char *)"RSA_PKCS1_SHA256\n"); break; case ECDSA_SECP384R1_SHA384: myprintf((char *)"ECDSA_SECP384R1_SHA384\n"); break; case RSA_PSS_RSAE_SHA384: myprintf((char *)"RSA_PSS_RSAE_SHA384\n"); break; case RSA_PKCS1_SHA384: myprintf((char *)"RSA_PKCS1_SHA384\n"); break; case RSA_PSS_RSAE_SHA512: myprintf((char *)"RSA_PSS_RSAE_SHA512\n"); break; case RSA_PKCS1_SHA512: myprintf((char *)"RSA_PKCS1_SHA512\n"); break; case ED25519: myprintf((char *)"ED25519\n"); break; //------------------------------------------------ case DILITHIUM2: myprintf((char *)"DILITHIUM2\n"); break; case DILITHIUM3: myprintf((char *)"DILITHIUM3\n"); break; case DILITHIUM5: myprintf((char *)"DILITHIUM5\n"); break; case MLDSA44: myprintf((char *)"MLDSA44\n"); break; case MLDSA65: myprintf((char *)"MLDSA65\n"); break; case MLDSA87: myprintf((char *)"MLDSA87\n"); break; case FALCON512: myprintf((char *)"FALCON512\n"); break; case FALCON1024: myprintf((char *)"FALCON1024\n"); break; case SPHINCSSHA2128FSIMPLE: myprintf((char *)"SPHINCS_SHA2_128F_SIMPLE\n"); break; case SPHINCSSHA2128SSIMPLE: myprintf((char *)"SPHINCS_SHA2_128S_SIMPLE\n"); break; case SPHINCSSHAKE128FSIMPLE: myprintf((char *)"SPHINCS_SHAKE_128F_SIMPLE\n"); break; //------------------------------------------------ case DILITHIUM2_P256: myprintf((char *)"DILITHIUM2 + P256\n"); break; default: myprintf((char *)"Non-standard\n"); break; } #endif } void logSigAlg(int sigAlg) { log(IO_PROTOCOL,(char *)"Signature Algorithm is ",NULL,0,NULL); nameSigAlg(sigAlg); } // log Encrypted Extensions Responses void logEncExt(ee_status *expected,ee_status *received) { #if VERBOSITY >= IO_PROTOCOL if (expected->early_data) { if (received->early_data) { log(IO_PROTOCOL,(char *)"Early Data Accepted\n",NULL,0,NULL); } else { log(IO_PROTOCOL,(char *)"Early Data was NOT Accepted\n",NULL,0,NULL); } } #endif #if VERBOSITY >= IO_DEBUG if (expected->alpn) { if (received->alpn) { log(IO_DEBUG,(char *)"ALPN extension acknowledged by server\n",NULL,0,NULL); } else { log(IO_DEBUG,(char *)"Warning - ALPN extension NOT acknowledged by server\n",NULL,0,NULL); } } if (expected->server_name) { if (received->server_name) { log(IO_DEBUG,(char *)"Server Name acknowledged\n",NULL,0,NULL); } else { log(IO_DEBUG,(char *)"Server Name NOT acknowledged\n",NULL,0,NULL); } } if (expected->max_frag_length) { if (received->max_frag_length) { log(IO_DEBUG,(char *)"Max frag length request acknowledged\n",NULL,0,NULL); } else { log(IO_DEBUG,(char *)"Max frag length request NOT acknowledged\n",NULL,0,NULL); } } #endif } // log server hello outputs void logServerHello(int cipher_suite,int pskid,octad *PK,octad *CK) { #if VERBOSITY >= IO_DEBUG log(IO_DEBUG,(char *)"Parsing serverHello\n",NULL,0,NULL); logCipherSuite(cipher_suite); if (pskid>=0) log(IO_DEBUG,(char *)"PSK Identity= ",(char *)"%d",pskid,NULL); if (PK->len>0) { log(IO_DEBUG,(char *)"Server Public Key= ",NULL,0,PK);//OCT_output(PK); } if (CK->len>0) { log(IO_DEBUG,(char *)"Cookie= ",NULL,0,CK); //OCT_output(CK); } log(IO_DEBUG,(char *)"\n",NULL,0,NULL); #endif } // log ticket details void logTicket(ticket *T) { #if VERBOSITY >= IO_DEBUG log(IO_DEBUG,(char *)"\nParsing Ticket\n",NULL,0,NULL); log(IO_DEBUG,(char *)"Ticket = ",NULL,0,&T->TICK); unsign32 minutes=T->lifetime/60; log(IO_DEBUG,(char *)"life time in minutes = ",(char *)"%d",minutes,NULL); log(IO_DEBUG,(char *)"PSK = ",NULL,0,&T->PSK); log(IO_DEBUG,(char *)"max_early_data = ",(char *)"%d",T->max_early_data,NULL); log(IO_DEBUG,(char *)"\n",NULL,0,NULL); #endif } // log a certificate in base64 void logCert(octad *CERT) { char b[5004]; log(IO_DEBUG,(char *)"-----BEGIN CERTIFICATE----- \n",NULL,0,NULL); #if VERBOSITY >= IO_DEBUG OCT_output_base64(CERT,5000,b); #endif log(IO_DEBUG,(char *)"",b,0,NULL); log(IO_DEBUG,(char *)"-----END CERTIFICATE----- \n",NULL,0,NULL); } // Construct Distinguished Name from DER encoding static int make_dn(octad *DN,octad *DER) { int i,c,len,n=0; DN->val[n++]='{'; c=X509_find_entity_property(DER,&X509_MN,0,&len); for (i=0;ival[n++]=DER->val[c+i]; } DN->val[n++]=','; c=X509_find_entity_property(DER,&X509_UN,0,&len); for (i=0;ival[n++]=DER->val[c+i]; } DN->val[n++]=','; c=X509_find_entity_property(DER,&X509_ON,0,&len); for (i=0;ival[n++]=DER->val[c+i]; } DN->val[n++]=','; c=X509_find_entity_property(DER,&X509_CN,0,&len); for (i=0;ival[n++]=DER->val[c+i]; } DN->val[n++]='}'; DN->val[n++]=0; DN->len=n; return n; } // log certificate details void logCertDetails(octad *PUBKEY,pktype pk,octad *SIG,pktype sg,octad *ISSUER,octad *SUBJECT) { #if VERBOSITY >= IO_DEBUG log(IO_DEBUG,(char *)"Parsing Certificate\n",NULL,0,NULL); log(IO_DEBUG,(char *)"Signature on Certificate is ",NULL,0,SIG); if (sg.type==X509_ECC) { log(IO_DEBUG,(char *)"ECDSA signature ",NULL,0,NULL); if (sg.curve==USE_NIST256) log(IO_DEBUG,(char *)"Curve is SECP256R1\n",NULL,0,NULL); if (sg.curve==USE_NIST384) log(IO_DEBUG,(char *)"Curve is SECP384R1\n",NULL,0,NULL); if (sg.curve==USE_NIST521) log(IO_DEBUG,(char *)"Curve is SECP521R1\n",NULL,0,NULL); if (sg.hash == X509_H256) log(IO_DEBUG,(char *)"Hashed with SHA256\n",NULL,0,NULL); if (sg.hash == X509_H384) log(IO_DEBUG,(char *)"Hashed with SHA384\n",NULL,0,NULL); if (sg.hash == X509_H512) log(IO_DEBUG,(char *)"Hashed with SHA512\n",NULL,0,NULL); } if (sg.type==X509_ECD) { log(IO_DEBUG,(char *)"EDDSA signature ",NULL,0,NULL); if (sg.curve==USE_ED25519) log(IO_DEBUG,(char *)"Curve is ED25519\n",NULL,0,NULL); if (sg.curve==USE_ED448) log(IO_DEBUG,(char *)"Curve is ED448\n",NULL,0,NULL); } if (sg.type==X509_RSA) log(IO_DEBUG,(char *)"RSA signature of length ",(char *)"%d",sg.curve,NULL); log(IO_DEBUG,(char *)"Public key from Certificate is ",NULL,0,PUBKEY); if (pk.type==X509_ECC) { log(IO_DEBUG,(char *)"ECC public key ",NULL,0,NULL); if (pk.curve==USE_NIST256) log(IO_DEBUG,(char *)"Curve is SECP256R1\n",NULL,0,NULL); if (pk.curve==USE_NIST384) log(IO_DEBUG,(char *)"Curve is SECP384R1\n",NULL,0,NULL); if (pk.curve==USE_NIST521) log(IO_DEBUG,(char *)"Curve is SECP521R1\n",NULL,0,NULL); } if (pk.type==X509_RSA) log(IO_DEBUG,(char *)"Certificate public key is RSA of length ",(char *)"%d",pk.curve,NULL); char dn[256]; octad DN={0,sizeof(dn),dn}; make_dn(&DN,ISSUER); log(IO_DEBUG,(char *)"Issuer is ",(char *)DN.val,0,NULL); make_dn(&DN,SUBJECT); log(IO_DEBUG,(char *)"Subject is ",(char *)DN.val,0,NULL); //log(IO_DEBUG,(char *)"Issuer is ",(char *)ISSUER->val,0,NULL); //log(IO_DEBUG,(char *)"Subject is ",(char *)SUBJECT->val,0,NULL); #endif } // log alert void logAlert(int detail) { #if VERBOSITY >= IO_PROTOCOL switch (detail) { case 0 : log(IO_PROTOCOL,(char *)"Close notify\n",NULL,0,NULL); break; case 10 : log(IO_PROTOCOL,(char *)"Unexpected Message\n",NULL,0,NULL); break; case 20 : log(IO_PROTOCOL,(char *)"Bad record mac\n",NULL,0,NULL); break; case 22 : log(IO_PROTOCOL,(char *)"Record overflow\n",NULL,0,NULL); break; case 40 : log(IO_PROTOCOL,(char *)"Handshake Failure (not TLS1.3?)\n",NULL,0,NULL); break; case 42 : log(IO_PROTOCOL,(char *)"Bad certificate\n",NULL,0,NULL); break; case 43 : log(IO_PROTOCOL,(char *)"Unsupported certificate\n",NULL,0,NULL); break; case 44 : log(IO_PROTOCOL,(char *)"Certificate revoked\n",NULL,0,NULL); break; case 45 : log(IO_PROTOCOL,(char *)"Certificate expired\n",NULL,0,NULL); break; case 46 : log(IO_PROTOCOL,(char *)"Certificate unknown\n",NULL,0,NULL); break; case 47 : log(IO_PROTOCOL,(char *)"Illegal parameter\n",NULL,0,NULL); break; case 48 : log(IO_PROTOCOL,(char *)"Unknown CA\n",NULL,0,NULL); break; case 49 : log(IO_PROTOCOL,(char *)"Access denied\n",NULL,0,NULL); break; case 50 : log(IO_PROTOCOL,(char *)"Decode error\n",NULL,0,NULL); break; case 51 : log(IO_PROTOCOL,(char *)"Decrypt error\n",NULL,0,NULL); break; case 70 : log(IO_PROTOCOL,(char *)"Protocol version\n",NULL,0,NULL); break; case 71 : log(IO_PROTOCOL,(char *)"Insufficient security\n",NULL,0,NULL); break; case 80 : log(IO_PROTOCOL,(char *)"Internal error\n",NULL,0,NULL); break; case 86 : log(IO_PROTOCOL,(char *)"Inappropriate fallback\n",NULL,0,NULL); break; case 90 : log(IO_PROTOCOL,(char *)"User cancelled\n",NULL,0,NULL); break; case 109 : log(IO_PROTOCOL,(char *)"Missing Extension\n",NULL,0,NULL); break; case 110 : log(IO_PROTOCOL,(char *)"Unsupported Extension\n",NULL,0,NULL); break; case 112 : log(IO_PROTOCOL,(char *)"Unrecognised name\n",NULL,0,NULL); break; case 113 : log(IO_PROTOCOL,(char *)"Bad certificate status response\n",NULL,0,NULL); break; case 115 : log(IO_PROTOCOL,(char *)"Unknown PSK identity \n",NULL,0,NULL); break; case 116 : log(IO_PROTOCOL,(char *)"Certificate required\n",NULL,0,NULL); break; case 120 : log(IO_PROTOCOL,(char *)"No application protocol\n",NULL,0,NULL); break; default: log(IO_PROTOCOL,(char *)"Unrecognised alert\n",NULL,0,NULL); break; } #endif } // process server function return void logServerResponse(ret r) { int rtn=r.err; if (rtn==0) return; #if VERBOSITY >= IO_DEBUG if (rtn<0) { // fatal errors - after logging we will send a server alert and close connection switch (rtn) { case NOT_TLS1_3: log(IO_DEBUG,(char *)"Not TLS1.3\n",NULL,0,NULL); break; case ID_MISMATCH: log(IO_DEBUG,(char *)"Identity Mismatch\n",NULL,0,NULL); break; case UNRECOGNIZED_EXT: log(IO_DEBUG,(char *)"Unrecognised Extension\n",NULL,0,NULL); break; case BAD_HELLO: log(IO_DEBUG,(char *)"Malformed Hello\n",NULL,0,NULL); break; case WRONG_MESSAGE: log(IO_DEBUG,(char *)"Message received out-of-order\n",NULL,0,NULL); break; case BAD_CERT_CHAIN: log(IO_DEBUG,(char *)"Bad Certificate Chain\n",NULL,0,NULL); break; case MISSING_REQUEST_CONTEXT: log(IO_DEBUG,(char *)"Missing Request Context\n",NULL,0,NULL); break; case AUTHENTICATION_FAILURE: log(IO_DEBUG,(char *)"Authentication Failure\n",NULL,0,NULL); break; case BAD_RECORD: log(IO_DEBUG,(char *)"Malformed Record received (max size exceeded?)\n",NULL,0,NULL); break; case BAD_TICKET: log(IO_DEBUG,(char *)"Malformed Ticket received\n",NULL,0,NULL); break; case NOT_EXPECTED: log(IO_DEBUG,(char *)"Unexpected message/extension\n",NULL,0,NULL); break; case CA_NOT_FOUND: log(IO_DEBUG,(char *)"Certificate Authority not found\n",NULL,0,NULL); break; case CERT_OUTOFDATE: log(IO_DEBUG,(char *)"Certificate is out of date\n",NULL,0,NULL); break; case MEM_OVERFLOW: log(IO_DEBUG,(char *)"Memory overflow\n",NULL,0,NULL); break; case FORBIDDEN_EXTENSION: log(IO_DEBUG,(char *)"Forbidden extension found\n",NULL,0,NULL); break; case MAX_EXCEEDED: log(IO_DEBUG,(char *)"Maximum record size exceeded\n",NULL,0,NULL); break; case CERT_VERIFY_FAIL: log(IO_DEBUG,(char *)"Certificate verification failure\n",NULL,0,NULL); break; case BAD_HANDSHAKE: log(IO_DEBUG,(char *)"Handshake protocol failure\n",NULL,0,NULL); break; case BAD_REQUEST_UPDATE: log(IO_DEBUG,(char *)"Bad Key update request\n",NULL,0,NULL); break; case MISSING_EXTENSIONS: log(IO_DEBUG,(char *)"Some extension(s) are missing\n",NULL,0,NULL); break; case BAD_MESSAGE: log(IO_DEBUG,(char *)"Malformed Message received\n",NULL,0,NULL); break; case EMPTY_CERT_CHAIN: log(IO_DEBUG,(char *)"Client Certificate required\n",NULL,0,NULL); break; default: log(IO_DEBUG,(char *)"Unknown Error\n",NULL,0,NULL); break; } } else { // server response requiring client action switch (rtn) { case TIMED_OUT : log(IO_DEBUG,(char *)"Time Out\n",NULL,0,NULL); break; case ALERT : log(IO_DEBUG,(char *)"Alert received from server\n",NULL,0,NULL); // received an alert break; default: break; } } #endif }