Browse code

tls: cert serial number can exceed uint64

- GH #3168

(cherry picked from commit 996bf4cad1d5645761fb80e66e435cedf29fa749)
(cherry picked from commit c4465cf37bbc925377d1eff0c2290203497dd36b)
(cherry picked from commit 8b2b13cdf7096dd746b976a3488d3fafd83c2f9a)

S-P Chan authored on 29/06/2022 23:19:18 • Daniel-Constantin Mierla committed on 15/09/2022 11:28:30
Showing 1 changed files
... ...
@@ -629,24 +629,35 @@ static int pv_validity(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
629 629
 }
630 630
 
631 631
 
632
-static int get_sn(str* res, int* ires, int local, sip_msg_t* msg)
632
+static int get_sn(str* res, int local, sip_msg_t* msg)
633 633
 {
634
-	static char buf[INT2STR_MAX_LEN];
634
+	static char buf[80]; // handle 256-bit > log(2^256,10)
635 635
 	X509* cert;
636 636
 	struct tcp_connection* c;
637
-	char* sn;
638
-	int num;
637
+	char* sn = NULL;
638
+	BIGNUM* bn = NULL;
639 639
 
640 640
 	if (get_cert(&cert, &c, msg, local) < 0) return -1;
641 641
 
642
-	num = ASN1_INTEGER_get(X509_get_serialNumber(cert));
643
-	sn = int2str(num, &res->len);
642
+	if (!(bn = BN_new())) goto error;
643
+	if (!ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), bn)) goto error;
644
+	if (!(sn = BN_bn2dec(bn)) || strlen(sn) > 80) goto error;
645
+
646
+	res->len = strlen(sn);
644 647
 	memcpy(buf, sn, res->len);
645 648
 	res->s = buf;
646
-	if (ires) *ires = num;
649
+
647 650
 	if (!local) X509_free(cert);
648 651
 	tcpconn_put(c);
652
+
653
+	BN_free(bn);
654
+	OPENSSL_free(sn);
649 655
 	return 0;
656
+
657
+ error:
658
+	if (sn) OPENSSL_free(sn);
659
+	if (bn) BN_free(bn);
660
+	return -1;
650 661
 }
651 662
 
652 663
 static int sel_sn(str* res, select_t* s, sip_msg_t* msg)
... ...
@@ -661,7 +672,7 @@ static int sel_sn(str* res, select_t* s, sip_msg_t* msg)
661 672
 		return -1;
662 673
 	}
663 674
 
664
-	return get_sn(res, NULL, local, msg);
675
+	return get_sn(res, local, msg);
665 676
 }
666 677
 
667 678
 
... ...
@@ -678,11 +689,11 @@ static int pv_sn(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
678 689
 		return pv_get_null(msg, param, res);
679 690
 	}
680 691
 	
681
-	if (get_sn(&res->rs, &res->ri, local, msg) < 0) {
692
+	if (get_sn(&res->rs, local, msg) < 0) {
682 693
 		return pv_get_null(msg, param, res);
683 694
 	}
684 695
 	
685
-	res->flags = PV_VAL_STR | PV_VAL_INT;
696
+	res->flags = PV_VAL_STR;
686 697
 	return 0;
687 698
 }
688 699