Meg leszel könnyítve, ha beledöglesz is

gpgsm az érintett termék neve, annyira felhasználóbarát, hogy mindenféle levelezési listáról kell összevadászni a legegyszerűbb használati esetet; valamint van két segítő démonja (gpg-agent, dirmngr), amik esszenciálisak, és automatikusan elindulnak, illetve nem esszenciálisak, és nem indulnak el maguktól, illetve adott esetben systemd kellhet hozzá, de az is lehet, hogy a RedHat ismét segített rajtam...
TL;DR: itt egy pelda az importalasra

Most éppen ennek örülhetek:

$ gpgconf --kill gpg-agent
gpgconf: invalid option "--kill"
$ systemctl --user stop gpg-agent
Failed to get D-Bus connection: No such file or directory

És ez még messze nem az igazi probléma, ez még csak egy mellékszál az alábbi mellékszál vizsgálata során:

$ gpgsm --import rootca.cert intermediateca.cert ee.cert
gpgsm: directory '~/.gnupg' created
gpgsm: keybox '~/.gnupg/pubring.kbx' created
gpgsm: total number processed: 3
gpgsm:               imported: 3
$ gpgsm --import ee.key
gpgsm: basic certificate checks failed - not imported
gpgsm: no issuer found in certificate
gpgsm: basic certificate checks failed - not imported
gpgsm: total number processed: 2
gpgsm:           not imported: 2

Szerk: Lehet, hogy a múlt évezredből megmaradt CentOS7.9 tényleg nem az igazi:

gpgsm: unknown hash algorithm `1.2.840.10045.4.3.3'

Ez a SHA384 lenne.

Hozzászólások

Szerkesztve: 2024. 01. 15., h – 11:25

Megpróbálhatom forrásból telepíteni, természetesen minden függőségének van két további függősége, eddig ennyi van:

libgpg-error-1.47
libgcrypt-1.10.3
sqlite3-3.44.2
npth-1.6
libassuan-2.5.6
libksba-1.6.5
gnupg-2.4.3

Szerk: Most jó részhez érkeztem:

gcc -std=gnu99 -I/usr/local/include -I/usr/local/include -I/usr/local/include -I/usr/local/include -I/usr/local/include  -I/usr/local/include -I/usr/local/include/p11-kit-1   -Wall -Wno-format-zero-length -Wno-pointer-sign -Wpointer-arith -m64 -std=c99  -m64 -L/usr/local/lib64 -Wl,-rpath,/usr/local/lib64 -o dirmngr dirmngr.o server.o crlcache.o crlfetch.o fakecrl.o certcache.o domaininfo.o workqueue.o loadswdb.o cdblib.o misc.o ocsp.o validate.o dns-stuff.o http.o http-common.o http-ntbtls.o ks-action.o ks-engine-hkp.o ks-engine-http.o ks-engine-finger.o ks-engine-kdns.o dns.o  ../common/libcommonpth.a -lresolv  -L/usr/local/lib64 -lassuan -L/usr/local/lib64 -lksba -lgpg-error -L/usr/local/lib64 -lnpth -lpthread  -L/usr/local/lib64 -lgnutls   -L/usr/local/lib64 -lgcrypt -L/usr/local/lib64 -lgpg-error
/usr/local/lib/gcc/x86_64-pc-linux-gnu/13.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: server.o: in function `cmd_ad_query':
server.c:(.text+0x47ff): undefined reference to `ks_ldap_help_variables'
collect2: error: ld returned 1 exit status
make[2]: *** [dirmngr] Error 1
make[2]: Leaving directory `/usr/local/src/gnupg-2.4.3/dirmngr'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/usr/local/src/gnupg-2.4.3'
make: *** [all] Error 2

Innen kellene jönnie: https://github.com/gpg/gnupg/blob/master/dirmngr/ks-engine-ldap.c

Első ötletem: yum install openldap-devel
 

Így már csak annyi gond van, hogy a derék fejlesztők nem tudnak róla, hogy használják a pthread-ot.

/usr/local/lib/gcc/x86_64-pc-linux-gnu/13.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: t_http_basic-dns.o: undefined reference to symbol 'pthread_sigmask@@GLIBC_2.2.5'
/usr/local/lib/gcc/x86_64-pc-linux-gnu/13.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: /lib64/libpthread.so.0: error adding symbols: DSO missing from command line

Ilyen volt:

/usr/bin/gpgsm --version
gpgsm (GnuPG) 2.0.22
libgcrypt 1.5.3
libksba 1.3.0
Home: ~/.gnupg
Supported algorithms:
Cipher: 3DES, AES, AES192, AES256, SERPENT128, SERPENT192, SERPENT256, SEED, CAMELLIA128, CAMELLIA192, CAMELLIA256
Pubkey: RSA
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224, WHIRLPOOL

Ilyen lett:

/usr/local/bin/gpgsm --version
gpgsm (GnuPG) 2.4.3
libgcrypt 1.10.3
libksba 1.6.5
Home: /root/.gnupg
Supported algorithms:
Cipher: 3DES, AES128, AES192, AES256, SERPENT128, SERPENT192, SERPENT256, SEED, CAMELLIA128, CAMELLIA192, CAMELLIA256
Pubkey: RSA, ECC, ECC
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224, WHIRLPOOL

Azt persze kétlem, hogy ettől bármi komoly javulás lenne.

Hát de, komoly javulásnak kéne lennie. Mivel a tanúsítványod ECDSA aláírt, ahhoz kell elliptikus görbés algoritmus támogatása (hiszen az ECDSA az elliptikus görbét használó titkosításon alapszik), ami láthatólag a 2.0.22-ben nem volt benne (hint: Pubkeynél csak RSA van a régiben).

De miért akarnád forrásból telepíteni?
Nem teljesen értelek.

Mit szeretnél elérni?

gpgsm: unknown hash algorithm `1.2.840.10045.4.3.3'

Nem, ez nem az SHA-384, hanem az ECDSA-SHA384. Az előbbi egy hashfüggvény, az utóbbi meg egy elektronikus aláírási séma, ahol SHA-384 a hashfüggvény. Két totál más kriptográfiai dologról van szó, az ECDSA-SHA384 az nem hash algoritmus. Nyilván nem fogja ismerni a gnupg, ha azt mondod neki, hogy ez egy hash algoritmus.

Szarul van kitöltve a tanúsítvány valószínűleg, hiányzik az Issuer mező.

Az X.509-es tanúsítványok kötelező mezőit a szabvány 7.2.1-es pontja tartalmazza, ahol egyértelmű, hogy az issuer az nem opcionális mező, hanem kötelező.

Ennek meg KELL felelnie a tanúsítványnak.

Kis fejlesztés után:

gpgsm: certchain.c:2266 no issuer found in certificate

Ilyesmi:

   2262   issuer = ksba_cert_get_issuer (cert, 0);
   2263   subject = ksba_cert_get_subject (cert, 0);
   2264   if (!issuer)
   2265     {
   2266       log_error ("certchain.c:2266 no issuer found in certificate\n");
   2267       rc = gpg_error (GPG_ERR_BAD_CERT);
   2268       goto leave;
   2269     }
 

Szóval a ksba_cert_get_issuer-t kellene megnézni. Adott esetben akár debuggerrel.

A ksba_cert_issuer dokumentációja szerint:

With idx given as 0, this function returns the Distinguished Name (DN) of the certificate issuer; this usually is the name of a certification authority (CA). The format of the returned string is in accordance with RFC-2253. NULL is returned if the DN is not available; This is a severe error and actually should have been caught by the certificate reading function.

A tanúsítványban az issuer mezőnek mi a tartalma? Van benne DN, vagy csak CN van benne, esetleg egy formátum nélküli string?

DN-nek kell lennie, hiszen az a globálisan egyedi azonosítója az entitásoknak - és ugye a DN az relative DN-ek sorozatából áll, megadott formátuma van. Lásd az X.501-es szabványt.

Az X.500-as szabványsorozat egész jól ki van találva, csak éppen komplex és kevesen implementálják igazán jól.

Melyik termék kukapozitív, azaz nem szabványkövető? Jó, ha megosztod a HUP közösségével, hogy más is elkerülje a hibát.

A cert részleteit kopizd már ki, főled az ISSUER részét, ha tudod.

Nem ismerem a gpg-t, de lehet h. nem konkrétan az van hogy a teljes ISSUER mező hiányzik. Lehet h. van ott ISSUER, szimplán csak a tartalma olyan, hogy az nem tetszik a gpg-nek. Azaz pl. ha olyan issuer adta ki a cert-et, ami a te géped tanúsítványtárában nem szerepel trusted CA-ként. Így a gpg nem tudja visszavezetni az ISSUER-t egy TRUSTED Root CA-ig a tanúsítvány láncolatban. Tipikusan ha self-signed a tanúsítvány, akkor szoktak ilyen gondok lenni. De ehhez látni kellene magát a tanúsítványt: ki a kiadó, ki a subject, validity notbefore/notafter, és a többi paraméter. A PKI nem egyszerű dolog :)

Szerkesztve: 2024. 01. 15., h – 17:54

Nyilván semmi köze semmihez, de ilyeneket látok a gpgsm --dump-cert kimenetében:

Issuer: CN=GovCA Főtanúsítványkiadó,2.5.4.97=#56415448552D3130353835353630,O=NISZ Nemzeti Infokommunikációs Szolgáltató Zrt.,L=Budapest,C=HU
...
authInfo: 1.3.6.1.5.5.7.48.2 (caIssuers)
...
Issuer: 1.2.840.113549.1.9.1=#6C7A73696761406D61696C2E616869762E6875,CN=Hokuszpok Root CA,O=Aprajafalva Certificate Authority,ST=Budapest,C=HU

Ez olyan, mintha ezeket nem ismerné:


1.2.840.113549.1.9.1  ... pkcs-9(9) emailAddress(1)
1.3.6.1.5.5.7.48.2    ... accessDescriptor(48) caIssuers(2)
2.5.4.97              ... ds(5) attributeType(4) organizationIdentifier(97)

A jó hír az, hogy van a libkbsa-hoz tesztprogram, pl. a t_reader.c
Na ebbe bele lehet fabrikálni a ksba_cert_get_issuer(cert, 0) hívást. Természetesen meg is találja, hogy pl.:

issuer="CN=GovCA Fokozott Tanúsítványkiadó,2.5.4.97=#56415448552D3130353835353630,O=NISZ Nemzeti Infokommunikációs Szolgáltató Zrt.,L=Budapest,C=HU"

Az amugy ezeknel (mert nem ez az elso ilyen jellegu blogbejegyzesed) nem megoldas, hogy felteszel valami dockerbe osszehanyt - mindenbol pont olyan verzio amivel mukodik - kontenert, esetleg kulon VM-be, es elfelejted a forrasbol forditast, meg a 10 eves szarok patcheleset a nightly build megfelelo koddarabkaival?

Csak egy otlet. Persze kevesbe izgalmas, mint backportolni a GPG-t PDP-11-re, meg blogolni is kevesbe lehetne rola.

A strange game. The only winning move is not to play. How about a nice game of chess?

Szerkesztve: 2024. 01. 16., k – 09:13

Pillanatnyi állapot összefoglalása:

* Titkos kulcsot nem importál pem/der-fájlból, például azért, mert a titkos kulcs nem valid certificate (ezt az logikát én sem értem).

* Viszont pkcs12-ből tud importálni cert-et és titkos kulcsot is.

* Nem akármilyen pkcs12-ből. A legújabb gpgsm [2.2.27 nem megy, 2.4.3 megy, mást még nem néztem] elboldogul az OpenSSL3 által -legacy opcióval létrehozott pkcs12 fájllal. (Az olyan, mint az OpenSSL1 által létrehozott pkcs12.)

* Az importálás olyan misztikusan bonyolult művelet, hogy nem önállóan végzi, hanem az agent bevonásával. Az agent nem szereti, ha töröljük alóla a ~/.gnupgp könyvtárat, tehát ha tiszta lappal szeretnénk kezdeni az egyes teszt-futásokat, akkor így próbálkozzunk:

killall gpg-agent
rm -rf ~/.gnupg
mkdir -p ~/.gnupg
gpgsm --pinentry-mode loopback --passphrase-fd 0 --import proba.p12 <proba.pwd
gpgsm: total number processed: 2
gpgsm:              unchanged: 1
gpgsm:       secret keys read: 1
gpgsm:   secret keys imported: 1
gpgsm -K
[keyboxd]
...

* A kulcs a ~/.gnupg/private-keys-v1.d könyvtárba kerül, a cert pedig sehová (akár volt chain a p12-ben, akár nem). Ami kicsit nyugtalanító, mert szerintem egy ~/gnupg/pubring.kbx nevű fájlba kellett volna kerüljön.

* Mivel kitaláltak egy újabb démont, a keyboxd-t (Váncsa István mondása jut eszembe: némely emberi agy egészen másképp működik, mint ahogy azt hétköznapi észjárással elképzelnénk.) Szóval a következő ötlet:

killall gpg-agent
rm -rf ~/.gnupg
echo '#use-keyboxd' >~/.gnupg/common.conf
gpgsm --pinentry-mode loopback --passphrase-fd 0 --import proba.p12 <proba.pwd
$ ls -l ~/.gnupg/
total 20
drwx------ 2 user group 4096 Jan 16 06:38 crls.d
drwx------ 2 user group 4096 Jan 16 06:38 private-keys-v1.d
-rw-r--r-- 1 user group 4477 Jan 16 06:38 pubring.kbx
-rw-r--r-- 1 user group 3308 Jan 16 06:38 pubring.kbx~

* További jó ötletnek tűnik, hogy a pkcs12-vel való bénázást elkerülendő simán átmásoljuk a ~/.gnupg tartalmát az etalon-gépről a production gépre (vagy pl. konténerbe), ha a gpg-verziókülönbség nem túl nagy a kettő között.

* Titkos kulcsot nem importál pem/der-fájlból, például azért, mert a titkos kulcs nem valid certificate (ezt az logikát én sem értem).

* Viszont pkcs12-ből tud importálni cert-et és titkos kulcsot is.

De hát ez a specifikációja:

--import [files]
Import the certificates from the PEM or binary encoded files as well as from signed-only messages. This command may also be used to import a secret key from a PKCS#12 file.
 
 

PEM-ből csak certet importál, PKCS#12-ből kulcsot és certet is, le van írva.

Jó, ha az ősködbe vesző múlt péntekre visszagondolok, a mese ott kezdődött, hogy a derék termék [default telepített verziója] nem ette meg a modern pkcs12-t. Sem az elavultat.

Viszont találtam leírást (na jó, nem egészen leírást, információtöredékeket a gnupg-users.gnupg.narkive.com -on), amikből úgy értettem, hogy szépen egyesével etessem meg vele a cert-fájlokat, kezdve a rootca-val, és befejezve az ee-vel, azután a privát kulcsot. Ez végül majdnem ment is, míg ki nem derül, hogy számára a privát kulcs egy hibás cert. Ekkor megpróbálkoztam verziófrissítéssel, és tádá, már eszi is az elavult pkcs12-t. (A modern-t még nem, ne sürgessük.)

Az OpenPGP egy szabványhalmaz (RFC 4880 és társai), ami mindenféle kriptoműveletre való, de főként üzenettitkosításra digitális aláírásra. Gyakorlatilag egy párhuzamos szabvány az X.509 és társai mellett.

OpenPGP kompatibilis aláírást rengeteg szoftverrel tudsz csinálni, nem kell ehhez gpgsm parancssori eszköz.

https://www.openpgp.org/software/developer/

De ha meg nem OpenPGP kompatibilis aláírás/titkosítás kell, hanem a gpgsm által is implementált CMS (Cryptographic Message Syntax) kompatibilis digitális aláírás, akkor miért nem openssl-t használtok, ha mindenképpen CLI eszköz kell? Az openssl cms alparancs jó erre.

Meg persze minden elterjedt programozási platformhoz van CMS library.

https://www.bouncycastle.org/docs/pkixdocs1.4/org/bouncycastle/cms/pack…

https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptograp…

https://www.php.net/manual/en/function.openssl-cms-sign.php

stb.

Tényleg nem értelek.

Nagy szellemek, ha találkoznak (ha szabad idéznem önmagamat):

Ilyenkor kezdek arra gondolni, hogy mégsem teljes hülyeség, amit a céges főarchitekt hajakendünk mondogat: legyen egy lista az engedélyezett komponensekről, és ha azon valami nincs rajta, akkor tessék megmagyarázni, hogy a már meglévők közül miért nem jó egyik sem. Például az OpenSSL smime/cms funkcionalitása szerintem pont jó lenne arra, amire itt ezt a gpgsm-et használni akarjak a derék kollégáim, és méghozzá három segéd-démon indítása nélkül működik.

Na de akkor miért baszol el NAPOKAT arra, hogy a béna kollégáid hülyeségét támogasd, ahelyett, hogy megmondod nekik, hogy balfaszok, és nem fogod támogatni a bénaságukat? Ezzel most két dolgot értél el:

  1. elpazaroltál rengeteg időt
  2. erősítetted bennük azt, hogy bármilyen butaságot megtehetnek, te majd gondolkodás nélkül támogatni akarod őket ebben, kerül amibe kerül.

Szidod itt a kollégákat, de közben gond nélkül támogatod őket, napokat elpocsékolva. Egy csapat attól is csapat, hogy ha valaki hülyeséget csinál, akkor más meg tudja neki mondani, hogy azt nem úgy kéne.

Miért nem az volt az első gondolatod, hogy "gyerekek, én ezzel nem fogok napokat szívni megint, ott az OpenSSL, használjátok azt.". Miért nem ezt mondtad nekik? Ennyire nincs dolgod?

Meta: igyekszem senkit sem szidni (talán a különböző fősodratú idealizmusok kiagyalóit kivébe [pl. aki szerint normális dolog egy  importáláshoz három(!) démont indítani.]), mivel attól tartok egy kicsit már így is eltértünk a le- és beszólások irányába, ami szerintem nem illik a hup baráti/szakmai légköréhez.

Értem. Tehát te szabadon minősíthetsz mindenki mást, elmondhatod a programokat mindennek, csak a te munkádat ne minősítsük, mert eltérünk a tárgytól.

Amúgy a GnuPG-nek oka van, hogy ágenssel működik. Az alapelve az, hogy a kriptográfiai kulcsokat a kliensprogram nem ismeri, csak a GnuPG. A kliensprogramok socketen az ágenshez kapcsolódnak, és a megfelelő kriptográfiai műveletek elvégzését az ágenssel végeztetik el. Így az ágens biztosítja azt, hogy a kulcshozzáférés biztonságos. Ő kéri be a kulcsjelszót tőled(és nem a felhasználói program), ő ügyel azért, hogy a kulcs jól legyen tárolva stb. Így egy titkos kulcshoz tartozó jelszót nem kell kiadni harmadik félnek, a GnuPG ágens felel csak érte, elég abban a programban megbízni.

Természetesen csinálhatsz te fizikai ágenst is, ha nem akarsz megbízni a GnuPG-ben, hiszen tárolhatod a privát kulcsodat smartcardon, és akkor a titkosítási műveletek a kártyán hajtódnak végre, ugyanúgy a programok a megfelelő szabványos protokollal csatlakoznak a kártyához és végrehajtatják a kriptográfiai műveleteket. Az egésznek a célja az, hogy a titkos kulcs, és a titkos kulcs jelszava a titkosításra igényt tartó programok felé nem ismert, mégis tudnak titkosítást végezni. Például egy Thunderbirdnek nem kell megadnod a titkos kulcsod jelszavát ahhoz, hogy alá tudjon írni egy levelet.

Hasonló, mint az ssh-agent, annak a létezésének is pont ez az oka.

Olvasás közben olyan kép alakul ki rólad bennem, mintha képtelen lennél eltemetni a halottad, akivel annak halála után még évekkel is együtt élsz. Odaülteted az asztalhoz, beszélsz hozzá, megfürdeted, átöltözteted. Amikor kicsit rendetlenkedik, akkor panaszkodsz a barátoknak. ;)

Amikor abba belegondolok, hogy ezt főállásban teszed, a nemzetgazdasági károkozás szó jut az eszembe és az, hogy:

De miért, de miért,  de miért?

A Centos7.9 elég régi, viszont az Ubuntu-22.04-en se sokkal jobb a történet, a problémás komponens maga a gpgsm, nem a platform, amin fut.

Off: Ilyenkor kezdek arra gondolni, hogy mégsem teljes hülyeség, amit a céges főarchitekt hajakendünk mondogat: legyen egy lista az engedélyezett komponensekről, és ha azon valami nincs rajta, akkor tessék megmagyarázni, hogy a már meglévők közül miért nem jó egyik sem. Például az OpenSSL smime/cms funkcionalitása szerintem pont jó lenne arra, amire itt ezt a gpgsm-et használni akarjak a derék kollégáim, és méghozzá három segéd-démon indítása nélkül működik.

De természetesen megpróbálhatjuk AIX-on is fordítani ezt a terméket, miért ne. Az első megálló a libgcrypt, amiben Assembly részek is vannak.

Kövi:

gpgsm: error running '/usr/local/bin/dirmngr': probably not installed

Hja, ahhoz GNUTLS is kellene. Ami, ha jól csalódom, szintén egy crypto-könyvtár, mint pl. az openSSL, vagy a NSS. Csak hát ugye a Not Invented Here szindróma miatt mindenki saját crypto-könyvtárat fejleszt.

Az is, meg milyen menő név már az hogy Nettle (magyarul csalán).
https://ftp.gnu.org/gnu/nettle/

Külön jó dolog, hogy libtool-t nem használ, hanem ezt szíveskedik beleilleszteni a szerkesztésbe: -Wl,-soname=libnettle.so.8

Természetesen létre is jön egy ilyen fájl:

# ls -l *=*
-rwxr-xr-x 1 root system 558694 Jan 16 11:53 name=libnettle.so.8

Ja és hogweed (disznófű). Nyilván az is települt volna, ha én nem tartom rosszul a billentyűzetet. (Vagy a holdfázis az ok.) Szerk: libgmp-ből kellett újabb.

Azt mondani sem kell, hogy a gnutls-nek nem elég a nettle, hogweed, tsn1, kell még a p11-kit, és ajánlott a libunbound.

Megint megbuktam, ismét elrejtettem az egyik header-file-t:

p11-kit/proxy.c:729:37: fatal error: p11-kit/proxy-generated.h: No such file or directory

Szerk: ezt egy hülye is kitalálhatta volna: Python3 kell neki, hogy meggenerálja az említett fájlt. Nyilván jó úton halad ez az ipar. Gyengébb jelleműeknek: --without-p11-kit

Mikor kiderült, hogy C++ is van a mesében, kicsit aggódni kezdtem, de most már nincs okom rá:

/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.1.0/5.4.0/include/c++/bits/stl_algobase.h:380:4: error: '_Static_assert' was not declared in this scope
    static_assert( __assignable::type::value, "type is not assignable" );

De még az assert-es gond előtt más is van, nevezetesen a GnuTLS az ő kegyes jóságában saját stddef.h-t hoz, saját max_align_t-vel, ami összevész a gcc azonos nevű fájljában lévő max_align_t-vel.

Szerk: Ennyit mára a tudomány és technika újdonságaiból (folyt.köv.):

printf '#include_next <stddef.h>\n' >gl/stddef.h
printf '#include_next <stddef.h>\n' >src/gl/stddef.h
printf '#include_next <assert.h>\n' >gl/assert.h
printf '#include_next <assert.h>\n' >src/gl/assert.h

sed_repl 's/static_assert (\(.*\));/_Static_assert (\1, "*sigh* C++");/' gl/malloca.c
sed_repl 's/static_assert (\(.*\));/_Static_assert (\1, "*sigh* C++");/' src/gl/malloca.c

A kérdés amúgy: miért kell neked GnuPG? Más OpenPGP implementáció nem játszik, aminek nincs köze a GNU szoftverekhez? Mihez kell neked egyáltalán OpenPGP?