Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libcotp for openSUSE:Factory checked 
in at 2025-12-22 22:52:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libcotp (Old)
 and      /work/SRC/openSUSE:Factory/.libcotp.new.1928 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libcotp"

Mon Dec 22 22:52:30 2025 rev:15 rq:1324209 version:3.1.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/libcotp/libcotp.changes  2024-10-11 
17:02:18.358637648 +0200
+++ /work/SRC/openSUSE:Factory/.libcotp.new.1928/libcotp.changes        
2025-12-22 22:56:12.806272288 +0100
@@ -1,0 +2,15 @@
+Mon Dec 22 16:42:11 UTC 2025 - Paolo Stivanin <[email protected]>
+
+- Update to 3.1.1:
+  * Security
+    + Memory sanitization: Sensitive cryptographic data is now
+      securely cleared from memory
+    + Buffer safety: Fixed potential overflow in base32 decoding
+  * Improvements
+    + Type safety: Migrated to unsigned integers for crypto operations
+    + Performance: Optimized base32 length calculations and removed
+      redundant calls
+    + Code quality: Simplified token formatting and enhanced
+      error handling
+
+-------------------------------------------------------------------

Old:
----
  v3.1.0.tar.gz
  v3.1.0.tar.gz.asc

New:
----
  v3.1.1.tar.gz
  v3.1.1.tar.gz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libcotp.spec ++++++
--- /var/tmp/diff_new_pack.RV3O3a/_old  2025-12-22 22:56:15.350377210 +0100
+++ /var/tmp/diff_new_pack.RV3O3a/_new  2025-12-22 22:56:15.394379024 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package libcotp
 #
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2025 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -24,7 +24,7 @@
 
 %define libsoname %{name}3
 Name:           libcotp
-Version:        3.1.0
+Version:        3.1.1
 Release:        0
 Summary:        C library for generating TOTP and HOTP
 License:        Apache-2.0


++++++ v3.1.0.tar.gz -> v3.1.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libcotp-3.1.0/CMakeLists.txt 
new/libcotp-3.1.1/CMakeLists.txt
--- old/libcotp-3.1.0/CMakeLists.txt    2024-10-04 13:42:33.000000000 +0200
+++ new/libcotp-3.1.1/CMakeLists.txt    2025-09-24 13:31:18.000000000 +0200
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 3.16)
-project(cotp VERSION "3.1.0" LANGUAGES "C")
+project(cotp VERSION "3.1.1" LANGUAGES "C")
 
 set(CMAKE_C_STANDARD 11)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libcotp-3.1.0/src/otp.c new/libcotp-3.1.1/src/otp.c
--- old/libcotp-3.1.0/src/otp.c 2024-10-04 13:42:33.000000000 +0200
+++ new/libcotp-3.1.1/src/otp.c 2025-09-24 13:31:18.000000000 +0200
@@ -6,6 +6,24 @@
 #include "whmac.h"
 #include "cotp.h"
 
+static void secure_memzero(void *p, size_t n) {
+    volatile unsigned char *vp = (volatile unsigned char *)p;
+    while (n--) {
+        *vp++ = 0;
+    }
+}
+
+static size_t b32_decoded_len_from_str(const char *s) {
+    if (!s) return 0;
+    size_t chars = 0;
+    for (const char *p = s; *p; ++p) {
+        if (*p != '=' && *p != ' ') {
+            ++chars;
+        }
+    }
+    return (chars * 5) / 8; // floor
+}
+
 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 #define REVERSE_BYTES(C, C_reverse_byte_order)           \
         for (int j = 0, i = 7; j < 8; j++, i--) {            \
@@ -83,9 +101,11 @@
         return NULL;
     }
 
+    size_t dlen = whmac_getlen(hd);
     int tk = truncate (hmac, digits, hd);
     whmac_freehandle (hd);
 
+    secure_memzero(hmac, dlen);
     free (hmac);
 
     *err_code = NO_ERROR;
@@ -183,10 +203,12 @@
 
     char *totp = get_steam_code (hmac, hd);
 
+    size_t dlen = whmac_getlen(hd);
     whmac_freehandle (hd);
 
     *err_code = NO_ERROR;
 
+    secure_memzero(hmac, dlen);
     free(hmac);
 
     return totp;
@@ -234,18 +256,19 @@
 get_steam_code (const unsigned char *hmac,
                 whmac_handle_t *hd)
 {
-    int offset = (hmac[whmac_getlen(hd)-1] & 0x0f);
+    size_t hlen = whmac_getlen(hd);
+    int offset = (hmac[hlen-1] & 0x0f);
 
     // Starting from the offset, take the successive 4 bytes while stripping 
the topmost bit to prevent it being handled as a signed integer
-    int bin_code = ((hmac[offset] & 0x7f) << 24) | ((hmac[offset + 1] & 0xff) 
<< 16) | ((hmac[offset + 2] & 0xff) << 8) | ((hmac[offset + 3] & 0xff));
+    uint32_t bin_code = ((uint32_t)(hmac[offset] & 0x7f) << 24) | 
((uint32_t)(hmac[offset + 1] & 0xff) << 16) | ((uint32_t)(hmac[offset + 2] & 
0xff) << 8) | ((uint32_t)(hmac[offset + 3] & 0xff));
 
     const char steam_alphabet[] = "23456789BCDFGHJKMNPQRTVWXY";
 
     char code[6];
     size_t steam_alphabet_len = strlen (steam_alphabet);
     for (int i = 0; i < 5; i++) {
-        int mod = (int)(bin_code % steam_alphabet_len);
-        bin_code = (int)(bin_code / steam_alphabet_len);
+        uint32_t mod = bin_code % (uint32_t)steam_alphabet_len;
+        bin_code = bin_code / (uint32_t)steam_alphabet_len;
         code[i] = steam_alphabet[mod];
     }
     code[5] = '\0';
@@ -260,13 +283,17 @@
           whmac_handle_t *hd)
 {
     // take the lower four bits of the last byte
-    int offset = hmac[whmac_getlen(hd) - 1] & 0x0f;
+    size_t hlen = whmac_getlen(hd);
+    int offset = hmac[hlen - 1] & 0x0f;
 
     // Starting from the offset, take the successive 4 bytes while stripping 
the topmost bit to prevent it being handled as a signed integer
-    int bin_code = ((hmac[offset] & 0x7f) << 24) | ((hmac[offset + 1] & 0xff) 
<< 16) | ((hmac[offset + 2] & 0xff) << 8) | ((hmac[offset + 3] & 0xff));
+    uint32_t bin_code = ((uint32_t)(hmac[offset] & 0x7f) << 24) | 
((uint32_t)(hmac[offset + 1] & 0xff) << 16) | ((uint32_t)(hmac[offset + 2] & 
0xff) << 8) | ((uint32_t)(hmac[offset + 3] & 0xff));
 
-    long long int DIGITS_POWER[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 
10000000, 100000000, 1000000000, 10000000000};
-    int token = (int)(bin_code % DIGITS_POWER[digits_length]);
+    uint64_t mod = 1;
+    for (int i = 0; i < digits_length; ++i) {
+        mod *= 10ULL;
+    }
+    int token = (int)(((uint64_t)bin_code) % mod);
 
     return token;
 }
@@ -277,13 +304,13 @@
               long        C,
               whmac_handle_t *hd)
 {
-    size_t secret_len = (size_t)((strlen(K) + 1.6 - 1) / 1.6);
-
     char *normalized_K = normalize_secret (K);
     if (normalized_K == NULL) {
         return NULL;
     }
 
+    size_t secret_len = b32_decoded_len_from_str(normalized_K);
+
     cotp_error_t err;
     unsigned char *secret = base32_decode (normalized_K, strlen(normalized_K), 
&err);
     free (normalized_K);
@@ -297,6 +324,7 @@
     err = whmac_setkey (hd, secret, secret_len);
     if (err) {
         fprintf (stderr, "Error while setting the cipher key.\n");
+        secure_memzero(secret, secret_len);
         free (secret);
         return NULL;
     }
@@ -306,6 +334,7 @@
     unsigned char *hmac = calloc (dlen, 1);
     if (hmac == NULL) {
         fprintf (stderr, "Error allocating memory");
+        secure_memzero(secret, secret_len);
         free (secret);
         return NULL;
     }
@@ -313,10 +342,13 @@
     ssize_t flen = whmac_finalize (hd, hmac, dlen);
     if (flen < 0) {
         fprintf (stderr, "Error getting digest\n");
+        secure_memzero(hmac, dlen);
         free (hmac);
+        secure_memzero(secret, secret_len);
         free (secret);
         return NULL;
     }
+    secure_memzero(secret, secret_len);
     free (secret);
 
     return hmac;
@@ -331,9 +363,8 @@
     if (token == NULL) {
         return NULL;
     }
-    char fmt[6];
-    sprintf (fmt, "%%0%dd", digits_length);
-    snprintf (token, digits_length + 1, fmt, tk);
+    // Print with leading zeros without building an intermediate format string
+    snprintf (token, digits_length + 1, "%0*d", digits_length, tk);
     return token;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libcotp-3.1.0/src/utils/base32.c 
new/libcotp-3.1.1/src/utils/base32.c
--- old/libcotp-3.1.0/src/utils/base32.c        2024-10-04 13:42:33.000000000 
+0200
+++ new/libcotp-3.1.1/src/utils/base32.c        2025-09-24 13:31:18.000000000 
+0200
@@ -153,7 +153,7 @@
             bits_left += BITS_PER_BYTE - BITS_PER_B32_BLOCK;
         }
     }
-    decoded_data[output_length-1] = '\0';
+    decoded_data[output_length] = '\0';
 
     free (user_data);
 

Reply via email to