@@ -69,7 +69,7 @@ if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then
6969fi
7070
7171# To find some devel packages, some rhel need to enable specific extra repos, but not on RedHat ubi images...
72- INSTALL_CMD_ADDL_REPO =" "
72+ INSTALL_CMD_ADDL_REPOS =" "
7373if [ ${ADJUSTED_ID} = " rhel" ] && [ ${ID} != " rhel" ]; then
7474 if [ ${MAJOR_VERSION_ID} = " 8" ]; then
7575 INSTALL_CMD_ADDL_REPOS=" --enablerepo powertools"
9393 INSTALL_CMD=" ${PKG_MGR_CMD} ${INSTALL_CMD_ADDL_REPOS} -y install --noplugins --setopt=install_weak_deps=0"
9494fi
9595
96+ # Install Time::Piece Perl module required by OpenSSL 3.0.18+ build system on CentOS 7/RHEL 7
97+ install_time_piece () {
98+ echo " (*) Ensuring Time::Piece Perl module is available for OpenSSL 3.0.18+ build..."
99+
100+ # Check if Time::Piece is already available (it's usually in Perl core)
101+ if perl -MTime::Piece -e ' exit 0' 2> /dev/null; then
102+ echo " (*) Time::Piece already available"
103+ return 0
104+ fi
105+
106+ echo " (*) Time::Piece not found, installing perl-Time-Piece package..."
107+
108+ # Install perl-Time-Piece package for CentOS 7/RHEL 7
109+ if ${INSTALL_CMD} perl-Time-Piece; then
110+ echo " (*) perl-Time-Piece installed for OpenSSL 3.0.18+ build"
111+ else
112+ echo " (!) Failed to install perl-Time-Piece package. This will cause OpenSSL 3.0.18+ build to fail"
113+ return 1
114+ fi
115+ }
116+
96117# Clean up
97118clean_up () {
98119 case ${ADJUSTED_ID} in
@@ -478,6 +499,130 @@ install_cpython() {
478499 curl -sSL -o " /tmp/python-src/${cpython_tgz_filename} " " ${cpython_tgz_url} "
479500 fi
480501}
502+ # Get system architecture for downloads
503+ get_architecture () {
504+ local architecture=" "
505+ case $( uname -m) in
506+ x86_64) architecture=" amd64" ;;
507+ aarch64 | armv8* ) architecture=" arm64" ;;
508+ aarch32 | armv7* | armvhf* ) architecture=" armhf" ;;
509+ i? 86) architecture=" 386" ;;
510+ * ) echo " (!) Architecture $( uname -m) unsupported" ; exit 1 ;;
511+ esac
512+ echo ${architecture}
513+ }
514+
515+ # Install cosign with multi-distro support
516+ install_cosign () {
517+
518+ COSIGN_VERSION=" latest"
519+ local cosign_url=' https://github.com/sigstore/cosign'
520+ local architecture=$( get_architecture)
521+
522+ find_version_from_git_tags COSIGN_VERSION " ${cosign_url} "
523+
524+ # Remove 'v' prefix if present for download URL
525+ local version_for_url=" ${COSIGN_VERSION# v} "
526+
527+ local cosign_filename=" /tmp/cosign_${version_for_url} _${architecture} .deb"
528+ local cosign_url=" https://github.com/sigstore/cosign/releases/download/v${version_for_url} /cosign_${version_for_url} _${architecture} .deb"
529+
530+ echo " Downloading cosign from: ${cosign_url} "
531+
532+ if curl -L -f --fail-with-body " ${cosign_url} " -o " $cosign_filename " 2> /dev/null; then
533+ echo " (*) Successfully downloaded cosign v${COSIGN_VERSION} "
534+ else
535+ echo -e " \n(!) Failed to fetch cosign v${COSIGN_VERSION} ..."
536+ # Try previous version
537+ find_prev_version_from_git_tags COSIGN_VERSION " https://github.com/sigstore/cosign"
538+ echo -e " \nAttempting to install previous cosign ${COSIGN_VERSION} version as fallback mechanism"
539+
540+ version_for_url=" ${COSIGN_VERSION# v} "
541+ cosign_filename=" /tmp/cosign_${version_for_url} _${architecture} .deb"
542+ cosign_url=" https://github.com/sigstore/cosign/releases/download/v${version_for_url} /cosign_${version_for_url} _${architecture} .deb"
543+
544+ if ! curl -L -f --fail-with-body " ${cosign_url} " -o " $cosign_filename " 2> /dev/null; then
545+ echo " (!) Failed to download cosign v${COSIGN_VERSION} as fallback"
546+ return 1
547+ fi
548+ fi
549+
550+ # Install the package
551+ if [ -f " $cosign_filename " ]; then
552+ dpkg -i " $cosign_filename "
553+ rm " $cosign_filename "
554+ echo " Installation of cosign succeeded with ${COSIGN_VERSION} ."
555+ else
556+ echo " (!) Failed to install cosign package"
557+ return 1
558+ fi
559+
560+ }
561+
562+ # COSIGN signature verification for python versions >= 3.14
563+ cosign_verification () {
564+ local VERSION=" $1 "
565+
566+ # Ensure cosign is installed
567+ if ! type cosign > /dev/null 2>&1 ; then
568+ echo " (*) cosign not found, installing..."
569+ if ! install_cosign; then
570+ echo " (!) Failed to install cosign"
571+ return 1
572+ fi
573+ else
574+ echo " (*) cosign is already available on the system"
575+ fi
576+
577+ echo " (*) Attempting COSIGN verification for Python ${VERSION} ..."
578+
579+ # Check if COSIGN signature files exist (these don't exist yet for Python releases)
580+ local cosign_sig_url=" ${cpython_tgz_url} .sig"
581+ local cosign_cert_url=" ${cpython_tgz_url} .pem"
582+
583+ # Download COSIGN signature and certificate files with proper error handling
584+ echo " (*) Checking for cosign signature files..."
585+ if ! curl -sSL -f --fail-with-body -o " /tmp/python-src/${cpython_tgz_filename} .sig" " ${cosign_sig_url} " 2> /dev/null; then
586+ echo " (!) COSIGN signature file not available for Python ${VERSION} "
587+ echo " Signature URL: ${cosign_sig_url} "
588+ return 1
589+ fi
590+
591+ if ! curl -sSL -f --fail-with-body -o " /tmp/python-src/${cpython_tgz_filename} .pem" " ${cosign_cert_url} " 2> /dev/null; then
592+ echo " (!) COSIGN certificate file not available for Python ${VERSION} "
593+ echo " Certificate URL: ${cosign_cert_url} "
594+ return 1
595+ fi
596+
597+ # Perform COSIGN verification
598+ if cosign verify-blob \
599+ --certificate " /tmp/python-src/${cpython_tgz_filename} .pem" \
600+ --signature " /tmp/python-src/${cpython_tgz_filename} .sig" \
601+ --certificate-identity-regexp=" .*" \
602+ --certificate-oidc-issuer-regexp=" .*" \
603+ " /tmp/python-src/${cpython_tgz_filename} " ; then
604+ echo " (*) COSIGN signature verification successful"
605+ return 0
606+ else
607+ echo " (!) COSIGN signature verification failed"
608+ return 1
609+ fi
610+ }
611+
612+ # GPG verification for python versions < 3.14
613+ gpg_verification () {
614+ echo " (*) Using GPG signature verification..."
615+ if [[ ${VERSION_CODENAME} = " centos7" ]] || [[ ${VERSION_CODENAME} = " rhel7" ]]; then
616+ receive_gpg_keys_centos7 PYTHON_SOURCE_GPG_KEYS
617+ else
618+ receive_gpg_keys PYTHON_SOURCE_GPG_KEYS
619+ fi
620+ echo " Downloading ${cpython_tgz_filename} .asc..."
621+ curl -sSL -o " /tmp/python-src/${cpython_tgz_filename} .asc" " ${cpython_tgz_url} .asc"
622+ gpg --verify " ${cpython_tgz_filename} .asc"
623+ echo " (*) GPG signature verification successful"
624+ }
625+
481626
482627install_from_source () {
483628 VERSION=$1
@@ -496,6 +641,8 @@ install_from_source() {
496641 case ${VERSION_CODENAME} in
497642 centos7|rhel7)
498643 check_packages perl-IPC-Cmd
644+ # Install Time::Piece Perl module required by OpenSSL 3.0.18+ build system
645+ install_time_piece
499646 install_openssl3
500647 ADDL_CONFIG_ARGS=" --with-openssl=${SSL_INSTALL_PATH} --with-openssl-rpath=${SSL_INSTALL_PATH} /lib"
501648 ;;
@@ -507,15 +654,27 @@ install_from_source() {
507654 install_prev_vers_cpython " ${VERSION} "
508655 fi
509656 fi ;
510- # Verify signature
511- if [[ ${VERSION_CODENAME} = " centos7" ]] || [[ ${VERSION_CODENAME} = " rhel7" ]]; then
512- receive_gpg_keys_centos7 PYTHON_SOURCE_GPG_KEYS
657+
658+ # Discontinuation of PGP signatures for releases of Python 3.14 or future versions
659+ # CPython release artifacts are additionally signed with Sigstore starting with the Python 3.11.0
660+ local major_version=$( echo " $VERSION " | cut -d. -f1)
661+ local minor_version=$( echo " $VERSION " | cut -d. -f2)
662+ echo " (*) Detected Python version: ${major_version} .${minor_version} "
663+ if (( major_version > 3 )) || { (( major_version == 3 )) && (( minor_version >= 14 )) ; }; then
664+ echo " (*) Python 3.14+ detected. Attempting cosign verification..."
665+ if cosign_verification " $VERSION " ; then
666+ echo " (*) COSIGN verification successful."
667+ else
668+ echo " (*) COSIGN verification failed or not available for Python ${VERSION} "
669+ echo " (*) WARNING: Installing Python ${VERSION} without signature verification"
670+ echo " (*) This is expected for newly released versions where cosign signatures are not yet available"
671+ echo " (*) Python 3.14+ discontinued PGP signatures in favor of cosign, but cosign signatures may take time to be published"
672+ fi
513673 else
514- receive_gpg_keys PYTHON_SOURCE_GPG_KEYS
674+ echo " (*) Python < 3.14 detected. Using GPG signature verification..."
675+ gpg_verification
676+ echo " (*) GPG verification successful."
515677 fi
516- echo " Downloading ${cpython_tgz_filename} .asc..."
517- curl -sSL -o " /tmp/python-src/${cpython_tgz_filename} .asc" " ${cpython_tgz_url} .asc"
518- gpg --verify " ${cpython_tgz_filename} .asc"
519678
520679 # Update min protocol for testing only - https://bugs.python.org/issue41561
521680 if [ -f /etc/pki/tls/openssl.cnf ]; then
0 commit comments