pubkey.c 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750
  1. /* pubkey.c - pubkey dispatcher
  2. * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
  3. * 2007, 2008 Free Software Foundation, Inc.
  4. *
  5. * This file is part of Libgcrypt.
  6. *
  7. * Libgcrypt is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser general Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * Libgcrypt is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include <config.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <errno.h>
  25. #include "g10lib.h"
  26. #include "mpi.h"
  27. #include "cipher.h"
  28. #include "ath.h"
  29. static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result,
  30. gcry_mpi_t *data, gcry_mpi_t *skey,
  31. int flags);
  32. static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr,
  33. gcry_mpi_t hash, gcry_mpi_t *skey);
  34. static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
  35. gcry_mpi_t *data, gcry_mpi_t *pkey,
  36. int (*cmp) (void *, gcry_mpi_t),
  37. void *opaque);
  38. /* A dummy extraspec so that we do not need to tests the extraspec
  39. field from the module specification against NULL and instead
  40. directly test the respective fields of extraspecs. */
  41. static pk_extra_spec_t dummy_extra_spec;
  42. /* This is the list of the default public-key ciphers included in
  43. libgcrypt. FIPS_ALLOWED indicated whether the algorithm is used in
  44. FIPS mode. */
  45. static struct pubkey_table_entry
  46. {
  47. gcry_pk_spec_t *pubkey;
  48. pk_extra_spec_t *extraspec;
  49. unsigned int algorithm;
  50. int fips_allowed;
  51. } pubkey_table[] =
  52. {
  53. #if USE_RSA
  54. { &_gcry_pubkey_spec_rsa,
  55. &_gcry_pubkey_extraspec_rsa, GCRY_PK_RSA, 1},
  56. #endif
  57. #if USE_ELGAMAL
  58. { &_gcry_pubkey_spec_elg,
  59. &_gcry_pubkey_extraspec_elg, GCRY_PK_ELG },
  60. { &_gcry_pubkey_spec_elg,
  61. &_gcry_pubkey_extraspec_elg, GCRY_PK_ELG_E },
  62. #endif
  63. #if USE_DSA
  64. { &_gcry_pubkey_spec_dsa,
  65. &_gcry_pubkey_extraspec_dsa, GCRY_PK_DSA, 1 },
  66. #endif
  67. #if USE_ECC
  68. { &_gcry_pubkey_spec_ecdsa,
  69. &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDSA, 0 },
  70. #endif
  71. { NULL, 0 },
  72. };
  73. /* List of registered ciphers. */
  74. static gcry_module_t pubkeys_registered;
  75. /* This is the lock protecting PUBKEYS_REGISTERED. */
  76. static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;;
  77. /* Flag to check wether the default pubkeys have already been
  78. registered. */
  79. static int default_pubkeys_registered;
  80. /* Convenient macro for registering the default digests. */
  81. #define REGISTER_DEFAULT_PUBKEYS \
  82. do \
  83. { \
  84. ath_mutex_lock (&pubkeys_registered_lock); \
  85. if (! default_pubkeys_registered) \
  86. { \
  87. pk_register_default (); \
  88. default_pubkeys_registered = 1; \
  89. } \
  90. ath_mutex_unlock (&pubkeys_registered_lock); \
  91. } \
  92. while (0)
  93. /* These dummy functions are used in case a cipher implementation
  94. refuses to provide it's own functions. */
  95. static gcry_err_code_t
  96. dummy_generate (int algorithm, unsigned int nbits, unsigned long dummy,
  97. gcry_mpi_t *skey, gcry_mpi_t **retfactors)
  98. {
  99. (void)algorithm;
  100. (void)nbits;
  101. (void)dummy;
  102. (void)skey;
  103. (void)retfactors;
  104. fips_signal_error ("using dummy public key function");
  105. return GPG_ERR_NOT_IMPLEMENTED;
  106. }
  107. static gcry_err_code_t
  108. dummy_check_secret_key (int algorithm, gcry_mpi_t *skey)
  109. {
  110. (void)algorithm;
  111. (void)skey;
  112. fips_signal_error ("using dummy public key function");
  113. return GPG_ERR_NOT_IMPLEMENTED;
  114. }
  115. static gcry_err_code_t
  116. dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
  117. gcry_mpi_t *pkey, int flags)
  118. {
  119. (void)algorithm;
  120. (void)resarr;
  121. (void)data;
  122. (void)pkey;
  123. (void)flags;
  124. fips_signal_error ("using dummy public key function");
  125. return GPG_ERR_NOT_IMPLEMENTED;
  126. }
  127. static gcry_err_code_t
  128. dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
  129. gcry_mpi_t *skey, int flags)
  130. {
  131. (void)algorithm;
  132. (void)result;
  133. (void)data;
  134. (void)skey;
  135. (void)flags;
  136. fips_signal_error ("using dummy public key function");
  137. return GPG_ERR_NOT_IMPLEMENTED;
  138. }
  139. static gcry_err_code_t
  140. dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
  141. gcry_mpi_t *skey)
  142. {
  143. (void)algorithm;
  144. (void)resarr;
  145. (void)data;
  146. (void)skey;
  147. fips_signal_error ("using dummy public key function");
  148. return GPG_ERR_NOT_IMPLEMENTED;
  149. }
  150. static gcry_err_code_t
  151. dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
  152. gcry_mpi_t *pkey,
  153. int (*cmp) (void *, gcry_mpi_t), void *opaquev)
  154. {
  155. (void)algorithm;
  156. (void)hash;
  157. (void)data;
  158. (void)pkey;
  159. (void)cmp;
  160. (void)opaquev;
  161. fips_signal_error ("using dummy public key function");
  162. return GPG_ERR_NOT_IMPLEMENTED;
  163. }
  164. static unsigned
  165. dummy_get_nbits (int algorithm, gcry_mpi_t *pkey)
  166. {
  167. (void)algorithm;
  168. (void)pkey;
  169. fips_signal_error ("using dummy public key function");
  170. return 0;
  171. }
  172. /* Internal function. Register all the pubkeys included in
  173. PUBKEY_TABLE. Returns zero on success or an error code. */
  174. static void
  175. pk_register_default (void)
  176. {
  177. gcry_err_code_t err = 0;
  178. int i;
  179. for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
  180. {
  181. #define pubkey_use_dummy(func) \
  182. if (! pubkey_table[i].pubkey->func) \
  183. pubkey_table[i].pubkey->func = dummy_##func;
  184. pubkey_use_dummy (generate);
  185. pubkey_use_dummy (check_secret_key);
  186. pubkey_use_dummy (encrypt);
  187. pubkey_use_dummy (decrypt);
  188. pubkey_use_dummy (sign);
  189. pubkey_use_dummy (verify);
  190. pubkey_use_dummy (get_nbits);
  191. #undef pubkey_use_dummy
  192. err = _gcry_module_add (&pubkeys_registered,
  193. pubkey_table[i].algorithm,
  194. (void *) pubkey_table[i].pubkey,
  195. (void *) pubkey_table[i].extraspec,
  196. NULL);
  197. }
  198. if (err)
  199. BUG ();
  200. }
  201. /* Internal callback function. Used via _gcry_module_lookup. */
  202. static int
  203. gcry_pk_lookup_func_name (void *spec, void *data)
  204. {
  205. gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) spec;
  206. char *name = (char *) data;
  207. const char **aliases = pubkey->aliases;
  208. int ret = stricmp (name, pubkey->name);
  209. while (ret && *aliases)
  210. ret = stricmp (name, *aliases++);
  211. return ! ret;
  212. }
  213. /* Internal function. Lookup a pubkey entry by it's name. */
  214. static gcry_module_t
  215. gcry_pk_lookup_name (const char *name)
  216. {
  217. gcry_module_t pubkey;
  218. pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name,
  219. gcry_pk_lookup_func_name);
  220. return pubkey;
  221. }
  222. /* Register a new pubkey module whose specification can be found in
  223. PUBKEY. On success, a new algorithm ID is stored in ALGORITHM_ID
  224. and a pointer representhing this module is stored in MODULE. */
  225. gcry_error_t
  226. _gcry_pk_register (gcry_pk_spec_t *pubkey,
  227. pk_extra_spec_t *extraspec,
  228. unsigned int *algorithm_id,
  229. gcry_module_t *module)
  230. {
  231. gcry_err_code_t err = GPG_ERR_NO_ERROR;
  232. gcry_module_t mod;
  233. /* We do not support module loading in fips mode. */
  234. if (fips_mode ())
  235. return gpg_error (GPG_ERR_NOT_SUPPORTED);
  236. ath_mutex_lock (&pubkeys_registered_lock);
  237. err = _gcry_module_add (&pubkeys_registered, 0,
  238. (void *) pubkey,
  239. (void *)(extraspec? extraspec : &dummy_extra_spec),
  240. &mod);
  241. ath_mutex_unlock (&pubkeys_registered_lock);
  242. if (! err)
  243. {
  244. *module = mod;
  245. *algorithm_id = mod->mod_id;
  246. }
  247. return err;
  248. }
  249. /* Unregister the pubkey identified by ID, which must have been
  250. registered with gcry_pk_register. */
  251. void
  252. gcry_pk_unregister (gcry_module_t module)
  253. {
  254. ath_mutex_lock (&pubkeys_registered_lock);
  255. _gcry_module_release (module);
  256. ath_mutex_unlock (&pubkeys_registered_lock);
  257. }
  258. static void
  259. release_mpi_array (gcry_mpi_t *array)
  260. {
  261. for (; *array; array++)
  262. {
  263. mpi_free(*array);
  264. *array = NULL;
  265. }
  266. }
  267. /****************
  268. * Map a string to the pubkey algo
  269. */
  270. int
  271. gcry_pk_map_name (const char *string)
  272. {
  273. gcry_module_t pubkey;
  274. int algorithm = 0;
  275. if (!string)
  276. return 0;
  277. REGISTER_DEFAULT_PUBKEYS;
  278. ath_mutex_lock (&pubkeys_registered_lock);
  279. pubkey = gcry_pk_lookup_name (string);
  280. if (pubkey)
  281. {
  282. algorithm = pubkey->mod_id;
  283. _gcry_module_release (pubkey);
  284. }
  285. ath_mutex_unlock (&pubkeys_registered_lock);
  286. return algorithm;
  287. }
  288. /* Map the public key algorithm whose ID is contained in ALGORITHM to
  289. a string representation of the algorithm name. For unknown
  290. algorithm IDs this functions returns "?". */
  291. const char *
  292. gcry_pk_algo_name (int algorithm)
  293. {
  294. gcry_module_t pubkey;
  295. const char *name;
  296. REGISTER_DEFAULT_PUBKEYS;
  297. ath_mutex_lock (&pubkeys_registered_lock);
  298. pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  299. if (pubkey)
  300. {
  301. name = ((gcry_pk_spec_t *) pubkey->spec)->name;
  302. _gcry_module_release (pubkey);
  303. }
  304. else
  305. name = "?";
  306. ath_mutex_unlock (&pubkeys_registered_lock);
  307. return name;
  308. }
  309. /* A special version of gcry_pk_algo name to return the first aliased
  310. name of the algorithm. This is required to adhere to the spki
  311. specs where the algorithm names are lowercase. */
  312. const char *
  313. _gcry_pk_aliased_algo_name (int algorithm)
  314. {
  315. const char *name = NULL;
  316. gcry_module_t module;
  317. REGISTER_DEFAULT_PUBKEYS;
  318. ath_mutex_lock (&pubkeys_registered_lock);
  319. module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  320. if (module)
  321. {
  322. gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) module->spec;
  323. name = pubkey->aliases? *pubkey->aliases : NULL;
  324. if (!name || !*name)
  325. name = pubkey->name;
  326. _gcry_module_release (module);
  327. }
  328. ath_mutex_unlock (&pubkeys_registered_lock);
  329. return name;
  330. }
  331. static void
  332. disable_pubkey_algo (int algorithm)
  333. {
  334. gcry_module_t pubkey;
  335. ath_mutex_lock (&pubkeys_registered_lock);
  336. pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  337. if (pubkey)
  338. {
  339. if (! (pubkey-> flags & FLAG_MODULE_DISABLED))
  340. pubkey->flags |= FLAG_MODULE_DISABLED;
  341. _gcry_module_release (pubkey);
  342. }
  343. ath_mutex_unlock (&pubkeys_registered_lock);
  344. }
  345. /****************
  346. * A USE of 0 means: don't care.
  347. */
  348. static gcry_err_code_t
  349. check_pubkey_algo (int algorithm, unsigned use)
  350. {
  351. gcry_err_code_t err = GPG_ERR_NO_ERROR;
  352. gcry_pk_spec_t *pubkey;
  353. gcry_module_t module;
  354. REGISTER_DEFAULT_PUBKEYS;
  355. ath_mutex_lock (&pubkeys_registered_lock);
  356. module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  357. if (module)
  358. {
  359. pubkey = (gcry_pk_spec_t *) module->spec;
  360. if (((use & GCRY_PK_USAGE_SIGN)
  361. && (! (pubkey->use & GCRY_PK_USAGE_SIGN)))
  362. || ((use & GCRY_PK_USAGE_ENCR)
  363. && (! (pubkey->use & GCRY_PK_USAGE_ENCR))))
  364. err = GPG_ERR_WRONG_PUBKEY_ALGO;
  365. else if (module->flags & FLAG_MODULE_DISABLED)
  366. err = GPG_ERR_PUBKEY_ALGO;
  367. _gcry_module_release (module);
  368. }
  369. else
  370. err = GPG_ERR_PUBKEY_ALGO;
  371. ath_mutex_unlock (&pubkeys_registered_lock);
  372. return err;
  373. }
  374. /****************
  375. * Return the number of public key material numbers
  376. */
  377. static int
  378. pubkey_get_npkey (int algorithm)
  379. {
  380. gcry_module_t pubkey;
  381. int npkey = 0;
  382. REGISTER_DEFAULT_PUBKEYS;
  383. ath_mutex_lock (&pubkeys_registered_lock);
  384. pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  385. if (pubkey)
  386. {
  387. npkey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_pkey);
  388. _gcry_module_release (pubkey);
  389. }
  390. ath_mutex_unlock (&pubkeys_registered_lock);
  391. return npkey;
  392. }
  393. /****************
  394. * Return the number of secret key material numbers
  395. */
  396. static int
  397. pubkey_get_nskey (int algorithm)
  398. {
  399. gcry_module_t pubkey;
  400. int nskey = 0;
  401. REGISTER_DEFAULT_PUBKEYS;
  402. ath_mutex_lock (&pubkeys_registered_lock);
  403. pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  404. if (pubkey)
  405. {
  406. nskey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_skey);
  407. _gcry_module_release (pubkey);
  408. }
  409. ath_mutex_unlock (&pubkeys_registered_lock);
  410. return nskey;
  411. }
  412. /****************
  413. * Return the number of signature material numbers
  414. */
  415. static int
  416. pubkey_get_nsig (int algorithm)
  417. {
  418. gcry_module_t pubkey;
  419. int nsig = 0;
  420. REGISTER_DEFAULT_PUBKEYS;
  421. ath_mutex_lock (&pubkeys_registered_lock);
  422. pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  423. if (pubkey)
  424. {
  425. nsig = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_sig);
  426. _gcry_module_release (pubkey);
  427. }
  428. ath_mutex_unlock (&pubkeys_registered_lock);
  429. return nsig;
  430. }
  431. /****************
  432. * Return the number of encryption material numbers
  433. */
  434. static int
  435. pubkey_get_nenc (int algorithm)
  436. {
  437. gcry_module_t pubkey;
  438. int nenc = 0;
  439. REGISTER_DEFAULT_PUBKEYS;
  440. ath_mutex_lock (&pubkeys_registered_lock);
  441. pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  442. if (pubkey)
  443. {
  444. nenc = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_enc);
  445. _gcry_module_release (pubkey);
  446. }
  447. ath_mutex_unlock (&pubkeys_registered_lock);
  448. return nenc;
  449. }
  450. /* Generate a new public key with algorithm ALGORITHM of size NBITS
  451. and return it at SKEY. USE_E depends on the ALGORITHM. GENPARMS
  452. is passed to the algorithm module if it features an extended
  453. generation function. RETFACTOR is used by some algorithms to
  454. return certain additional information which are in general not
  455. required.
  456. The function returns the error code number or 0 on success. */
  457. static gcry_err_code_t
  458. pubkey_generate (int algorithm,
  459. unsigned int nbits,
  460. unsigned long use_e,
  461. gcry_sexp_t genparms,
  462. gcry_mpi_t *skey, gcry_mpi_t **retfactors,
  463. gcry_sexp_t *r_extrainfo)
  464. {
  465. gcry_err_code_t ec = GPG_ERR_PUBKEY_ALGO;
  466. gcry_module_t pubkey;
  467. REGISTER_DEFAULT_PUBKEYS;
  468. ath_mutex_lock (&pubkeys_registered_lock);
  469. pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  470. if (pubkey)
  471. {
  472. pk_extra_spec_t *extraspec = pubkey->extraspec;
  473. if (extraspec && extraspec->ext_generate)
  474. {
  475. /* Use the extended generate function. */
  476. ec = extraspec->ext_generate
  477. (algorithm, nbits, use_e, genparms, skey, retfactors, r_extrainfo);
  478. }
  479. else
  480. {
  481. /* Use the standard generate function. */
  482. ec = ((gcry_pk_spec_t *) pubkey->spec)->generate
  483. (algorithm, nbits, use_e, skey, retfactors);
  484. }
  485. _gcry_module_release (pubkey);
  486. }
  487. ath_mutex_unlock (&pubkeys_registered_lock);
  488. return ec;
  489. }
  490. static gcry_err_code_t
  491. pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
  492. {
  493. gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
  494. gcry_module_t pubkey;
  495. REGISTER_DEFAULT_PUBKEYS;
  496. ath_mutex_lock (&pubkeys_registered_lock);
  497. pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  498. if (pubkey)
  499. {
  500. err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key
  501. (algorithm, skey);
  502. _gcry_module_release (pubkey);
  503. }
  504. ath_mutex_unlock (&pubkeys_registered_lock);
  505. return err;
  506. }
  507. /****************
  508. * This is the interface to the public key encryption. Encrypt DATA
  509. * with PKEY and put it into RESARR which should be an array of MPIs
  510. * of size PUBKEY_MAX_NENC (or less if the algorithm allows this -
  511. * check with pubkey_get_nenc() )
  512. */
  513. static gcry_err_code_t
  514. pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
  515. gcry_mpi_t *pkey, int flags)
  516. {
  517. gcry_pk_spec_t *pubkey;
  518. gcry_module_t module;
  519. gcry_err_code_t rc;
  520. int i;
  521. /* Note: In fips mode DBG_CIPHER will enver evaluate to true but as
  522. an extra failsafe protection we explicitly test for fips mode
  523. here. */
  524. if (DBG_CIPHER && !fips_mode ())
  525. {
  526. log_debug ("pubkey_encrypt: algo=%d\n", algorithm);
  527. for(i = 0; i < pubkey_get_npkey (algorithm); i++)
  528. log_mpidump (" pkey:", pkey[i]);
  529. log_mpidump (" data:", data);
  530. }
  531. ath_mutex_lock (&pubkeys_registered_lock);
  532. module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  533. if (module)
  534. {
  535. pubkey = (gcry_pk_spec_t *) module->spec;
  536. rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags);
  537. _gcry_module_release (module);
  538. goto ready;
  539. }
  540. rc = GPG_ERR_PUBKEY_ALGO;
  541. ready:
  542. ath_mutex_unlock (&pubkeys_registered_lock);
  543. if (!rc && DBG_CIPHER && !fips_mode ())
  544. {
  545. for(i = 0; i < pubkey_get_nenc (algorithm); i++)
  546. log_mpidump(" encr:", resarr[i] );
  547. }
  548. return rc;
  549. }
  550. /****************
  551. * This is the interface to the public key decryption.
  552. * ALGO gives the algorithm to use and this implicitly determines
  553. * the size of the arrays.
  554. * result is a pointer to a mpi variable which will receive a
  555. * newly allocated mpi or NULL in case of an error.
  556. */
  557. static gcry_err_code_t
  558. pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
  559. gcry_mpi_t *skey, int flags)
  560. {
  561. gcry_pk_spec_t *pubkey;
  562. gcry_module_t module;
  563. gcry_err_code_t rc;
  564. int i;
  565. *result = NULL; /* so the caller can always do a mpi_free */
  566. if (DBG_CIPHER && !fips_mode ())
  567. {
  568. log_debug ("pubkey_decrypt: algo=%d\n", algorithm);
  569. for(i = 0; i < pubkey_get_nskey (algorithm); i++)
  570. log_mpidump (" skey:", skey[i]);
  571. for(i = 0; i < pubkey_get_nenc (algorithm); i++)
  572. log_mpidump (" data:", data[i]);
  573. }
  574. ath_mutex_lock (&pubkeys_registered_lock);
  575. module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  576. if (module)
  577. {
  578. pubkey = (gcry_pk_spec_t *) module->spec;
  579. rc = pubkey->decrypt (algorithm, result, data, skey, flags);
  580. _gcry_module_release (module);
  581. goto ready;
  582. }
  583. rc = GPG_ERR_PUBKEY_ALGO;
  584. ready:
  585. ath_mutex_unlock (&pubkeys_registered_lock);
  586. if (!rc && DBG_CIPHER && !fips_mode ())
  587. log_mpidump (" plain:", *result);
  588. return rc;
  589. }
  590. /****************
  591. * This is the interface to the public key signing.
  592. * Sign data with skey and put the result into resarr which
  593. * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
  594. * algorithm allows this - check with pubkey_get_nsig() )
  595. */
  596. static gcry_err_code_t
  597. pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
  598. gcry_mpi_t *skey)
  599. {
  600. gcry_pk_spec_t *pubkey;
  601. gcry_module_t module;
  602. gcry_err_code_t rc;
  603. int i;
  604. if (DBG_CIPHER && !fips_mode ())
  605. {
  606. log_debug ("pubkey_sign: algo=%d\n", algorithm);
  607. for(i = 0; i < pubkey_get_nskey (algorithm); i++)
  608. log_mpidump (" skey:", skey[i]);
  609. log_mpidump(" data:", data );
  610. }
  611. ath_mutex_lock (&pubkeys_registered_lock);
  612. module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  613. if (module)
  614. {
  615. pubkey = (gcry_pk_spec_t *) module->spec;
  616. rc = pubkey->sign (algorithm, resarr, data, skey);
  617. _gcry_module_release (module);
  618. goto ready;
  619. }
  620. rc = GPG_ERR_PUBKEY_ALGO;
  621. ready:
  622. ath_mutex_unlock (&pubkeys_registered_lock);
  623. if (!rc && DBG_CIPHER && !fips_mode ())
  624. for (i = 0; i < pubkey_get_nsig (algorithm); i++)
  625. log_mpidump (" sig:", resarr[i]);
  626. return rc;
  627. }
  628. /****************
  629. * Verify a public key signature.
  630. * Return 0 if the signature is good
  631. */
  632. static gcry_err_code_t
  633. pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
  634. gcry_mpi_t *pkey,
  635. int (*cmp)(void *, gcry_mpi_t), void *opaquev)
  636. {
  637. gcry_pk_spec_t *pubkey;
  638. gcry_module_t module;
  639. gcry_err_code_t rc;
  640. int i;
  641. if (DBG_CIPHER && !fips_mode ())
  642. {
  643. log_debug ("pubkey_verify: algo=%d\n", algorithm);
  644. for (i = 0; i < pubkey_get_npkey (algorithm); i++)
  645. log_mpidump (" pkey:", pkey[i]);
  646. for (i = 0; i < pubkey_get_nsig (algorithm); i++)
  647. log_mpidump (" sig:", data[i]);
  648. log_mpidump (" hash:", hash);
  649. }
  650. ath_mutex_lock (&pubkeys_registered_lock);
  651. module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  652. if (module)
  653. {
  654. pubkey = (gcry_pk_spec_t *) module->spec;
  655. rc = pubkey->verify (algorithm, hash, data, pkey, cmp, opaquev);
  656. _gcry_module_release (module);
  657. goto ready;
  658. }
  659. rc = GPG_ERR_PUBKEY_ALGO;
  660. ready:
  661. ath_mutex_unlock (&pubkeys_registered_lock);
  662. return rc;
  663. }
  664. /* Internal function. */
  665. static gcry_err_code_t
  666. sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
  667. gcry_mpi_t *elements, const char *algo_name)
  668. {
  669. gcry_err_code_t err = 0;
  670. int i, idx;
  671. const char *name;
  672. gcry_sexp_t list;
  673. for (name = element_names, idx = 0; *name && !err; name++, idx++)
  674. {
  675. list = gcry_sexp_find_token (key_sexp, name, 1);
  676. if (!list)
  677. elements[idx] = NULL;
  678. else
  679. {
  680. elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
  681. gcry_sexp_release (list);
  682. if (!elements[idx])
  683. err = GPG_ERR_INV_OBJ;
  684. }
  685. }
  686. if (!err)
  687. {
  688. /* Check that all elements are available. */
  689. for (name = element_names, idx = 0; *name; name++, idx++)
  690. if (!elements[idx])
  691. break;
  692. if (*name)
  693. {
  694. err = GPG_ERR_NO_OBJ;
  695. /* Some are missing. Before bailing out we test for
  696. optional parameters. */
  697. if (algo_name && !strcmp (algo_name, "RSA")
  698. && !strcmp (element_names, "nedpqu") )
  699. {
  700. /* This is RSA. Test whether we got N, E and D and that
  701. the optional P, Q and U are all missing. */
  702. if (elements[0] && elements[1] && elements[2]
  703. && !elements[3] && !elements[4] && !elements[5])
  704. err = 0;
  705. }
  706. }
  707. }
  708. if (err)
  709. {
  710. for (i = 0; i < idx; i++)
  711. if (elements[i])
  712. gcry_free (elements[i]);
  713. }
  714. return err;
  715. }
  716. /* Internal function used for ecc. Note, that this function makes use
  717. of its intimate knowledge about the ECC parameters from ecc.c. */
  718. static gcry_err_code_t
  719. sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
  720. gcry_mpi_t *elements, pk_extra_spec_t *extraspec)
  721. {
  722. gcry_err_code_t err = 0;
  723. int idx;
  724. const char *name;
  725. gcry_sexp_t list;
  726. /* Clear the array for easier error cleanup. */
  727. for (name = element_names, idx = 0; *name; name++, idx++)
  728. elements[idx] = NULL;
  729. gcry_assert (idx >= 6); /* We know that ECC has at least 6 elements. */
  730. /* Init the array with the available curve parameters. */
  731. for (name = element_names, idx = 0; *name && !err; name++, idx++)
  732. {
  733. list = gcry_sexp_find_token (key_sexp, name, 1);
  734. if (!list)
  735. elements[idx] = NULL;
  736. else
  737. {
  738. elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
  739. gcry_sexp_release (list);
  740. if (!elements[idx])
  741. {
  742. err = GPG_ERR_INV_OBJ;
  743. goto leave;
  744. }
  745. }
  746. }
  747. /* Check whether a curve parameter has been given and then fill any
  748. missing elements. */
  749. list = gcry_sexp_find_token (key_sexp, "curve", 5);
  750. if (list)
  751. {
  752. if (extraspec->get_param)
  753. {
  754. char *curve;
  755. gcry_mpi_t params[6];
  756. for (idx = 0; idx < DIM(params); idx++)
  757. params[idx] = NULL;
  758. curve = _gcry_sexp_nth_string (list, 1);
  759. gcry_sexp_release (list);
  760. if (!curve)
  761. {
  762. /* No curve name given (or out of core). */
  763. err = GPG_ERR_INV_OBJ;
  764. goto leave;
  765. }
  766. err = extraspec->get_param (curve, params);
  767. gcry_free (curve);
  768. if (err)
  769. goto leave;
  770. for (idx = 0; idx < DIM(params); idx++)
  771. {
  772. if (!elements[idx])
  773. elements[idx] = params[idx];
  774. else
  775. mpi_free (params[idx]);
  776. }
  777. }
  778. else
  779. {
  780. gcry_sexp_release (list);
  781. err = GPG_ERR_INV_OBJ; /* "curve" given but ECC not supported. */
  782. goto leave;
  783. }
  784. }
  785. /* Check that all parameters are known. */
  786. for (name = element_names, idx = 0; *name; name++, idx++)
  787. if (!elements[idx])
  788. {
  789. err = GPG_ERR_NO_OBJ;
  790. goto leave;
  791. }
  792. leave:
  793. if (err)
  794. {
  795. for (name = element_names, idx = 0; *name; name++, idx++)
  796. if (elements[idx])
  797. gcry_free (elements[idx]);
  798. }
  799. return err;
  800. }
  801. /****************
  802. * Convert a S-Exp with either a private or a public key to our
  803. * internal format. Currently we do only support the following
  804. * algorithms:
  805. * dsa
  806. * rsa
  807. * openpgp-dsa
  808. * openpgp-rsa
  809. * openpgp-elg
  810. * openpgp-elg-sig
  811. * ecdsa
  812. * Provide a SE with the first element be either "private-key" or
  813. * or "public-key". It is followed by a list with its first element
  814. * be one of the above algorithm identifiers and the remaning
  815. * elements are pairs with parameter-id and value.
  816. * NOTE: we look through the list to find a list beginning with
  817. * "private-key" or "public-key" - the first one found is used.
  818. *
  819. * Returns: A pointer to an allocated array of MPIs if the return value is
  820. * zero; the caller has to release this array.
  821. *
  822. * Example of a DSA public key:
  823. * (private-key
  824. * (dsa
  825. * (p <mpi>)
  826. * (g <mpi>)
  827. * (y <mpi>)
  828. * (x <mpi>)
  829. * )
  830. * )
  831. * The <mpi> are expected to be in GCRYMPI_FMT_USG
  832. */
  833. static gcry_err_code_t
  834. sexp_to_key (gcry_sexp_t sexp, int want_private, gcry_mpi_t **retarray,
  835. gcry_module_t *retalgo)
  836. {
  837. gcry_err_code_t err = 0;
  838. gcry_sexp_t list, l2;
  839. char *name;
  840. const char *elems;
  841. gcry_mpi_t *array;
  842. gcry_module_t module;
  843. gcry_pk_spec_t *pubkey;
  844. pk_extra_spec_t *extraspec;
  845. int is_ecc;
  846. /* Check that the first element is valid. */
  847. list = gcry_sexp_find_token (sexp,
  848. want_private? "private-key":"public-key", 0);
  849. if (!list)
  850. return GPG_ERR_INV_OBJ; /* Does not contain a key object. */
  851. l2 = gcry_sexp_cadr( list );
  852. gcry_sexp_release ( list );
  853. list = l2;
  854. name = _gcry_sexp_nth_string (list, 0);
  855. if (!name)
  856. {
  857. gcry_sexp_release ( list );
  858. return GPG_ERR_INV_OBJ; /* Invalid structure of object. */
  859. }
  860. ath_mutex_lock (&pubkeys_registered_lock);
  861. module = gcry_pk_lookup_name (name);
  862. ath_mutex_unlock (&pubkeys_registered_lock);
  863. /* Fixme: We should make sure that an ECC key is always named "ecc"
  864. and not "ecdsa". "ecdsa" should be used for the signature
  865. itself. We need a function to test whether an algorithm given
  866. with a key is compatible with an application of the key (signing,
  867. encryption). For RSA this is easy, but ECC is the first
  868. algorithm which has many flavours. */
  869. is_ecc = ( !strcmp (name, "ecdsa") || !strcmp (name, "ecc") );
  870. gcry_free (name);
  871. if (!module)
  872. {
  873. gcry_sexp_release (list);
  874. return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
  875. }
  876. else
  877. {
  878. pubkey = (gcry_pk_spec_t *) module->spec;
  879. extraspec = module->extraspec;
  880. }
  881. elems = want_private ? pubkey->elements_skey : pubkey->elements_pkey;
  882. array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
  883. if (!array)
  884. err = gpg_err_code_from_errno (errno);
  885. if (!err)
  886. {
  887. if (is_ecc)
  888. err = sexp_elements_extract_ecc (list, elems, array, extraspec);
  889. else
  890. err = sexp_elements_extract (list, elems, array, pubkey->name);
  891. }
  892. gcry_sexp_release (list);
  893. if (err)
  894. {
  895. gcry_free (array);
  896. ath_mutex_lock (&pubkeys_registered_lock);
  897. _gcry_module_release (module);
  898. ath_mutex_unlock (&pubkeys_registered_lock);
  899. }
  900. else
  901. {
  902. *retarray = array;
  903. *retalgo = module;
  904. }
  905. return err;
  906. }
  907. static gcry_err_code_t
  908. sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
  909. gcry_module_t *retalgo)
  910. {
  911. gcry_err_code_t err = 0;
  912. gcry_sexp_t list, l2;
  913. char *name;
  914. const char *elems;
  915. gcry_mpi_t *array;
  916. gcry_module_t module;
  917. gcry_pk_spec_t *pubkey;
  918. /* Check that the first element is valid. */
  919. list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
  920. if (!list)
  921. return GPG_ERR_INV_OBJ; /* Does not contain a signature value object. */
  922. l2 = gcry_sexp_nth (list, 1);
  923. if (!l2)
  924. {
  925. gcry_sexp_release (list);
  926. return GPG_ERR_NO_OBJ; /* No cadr for the sig object. */
  927. }
  928. name = _gcry_sexp_nth_string (l2, 0);
  929. if (!name)
  930. {
  931. gcry_sexp_release (list);
  932. gcry_sexp_release (l2);
  933. return GPG_ERR_INV_OBJ; /* Invalid structure of object. */
  934. }
  935. else if (!strcmp (name, "flags"))
  936. {
  937. /* Skip flags, since they are not used but here just for the
  938. sake of consistent S-expressions. */
  939. gcry_free (name);
  940. gcry_sexp_release (l2);
  941. l2 = gcry_sexp_nth (list, 2);
  942. if (!l2)
  943. {
  944. gcry_sexp_release (list);
  945. return GPG_ERR_INV_OBJ;
  946. }
  947. name = _gcry_sexp_nth_string (l2, 0);
  948. }
  949. ath_mutex_lock (&pubkeys_registered_lock);
  950. module = gcry_pk_lookup_name (name);
  951. ath_mutex_unlock (&pubkeys_registered_lock);
  952. gcry_free (name);
  953. name = NULL;
  954. if (!module)
  955. {
  956. gcry_sexp_release (l2);
  957. gcry_sexp_release (list);
  958. return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
  959. }
  960. else
  961. pubkey = (gcry_pk_spec_t *) module->spec;
  962. elems = pubkey->elements_sig;
  963. array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
  964. if (!array)
  965. err = gpg_err_code_from_errno (errno);
  966. if (!err)
  967. err = sexp_elements_extract (list, elems, array, NULL);
  968. gcry_sexp_release (l2);
  969. gcry_sexp_release (list);
  970. if (err)
  971. {
  972. ath_mutex_lock (&pubkeys_registered_lock);
  973. _gcry_module_release (module);
  974. ath_mutex_unlock (&pubkeys_registered_lock);
  975. gcry_free (array);
  976. }
  977. else
  978. {
  979. *retarray = array;
  980. *retalgo = module;
  981. }
  982. return err;
  983. }
  984. /****************
  985. * Take sexp and return an array of MPI as used for our internal decrypt
  986. * function.
  987. * s_data = (enc-val
  988. * [(flags [pkcs1])]
  989. * (<algo>
  990. * (<param_name1> <mpi>)
  991. * ...
  992. * (<param_namen> <mpi>)
  993. * ))
  994. * RET_MODERN is set to true when at least an empty flags list has been found.
  995. */
  996. static gcry_err_code_t
  997. sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
  998. int *ret_modern, int *ret_want_pkcs1, int *flags)
  999. {
  1000. gcry_err_code_t err = 0;
  1001. gcry_sexp_t list = NULL, l2 = NULL;
  1002. gcry_pk_spec_t *pubkey = NULL;
  1003. gcry_module_t module = NULL;
  1004. char *name = NULL;
  1005. size_t n;
  1006. int parsed_flags = 0;
  1007. const char *elems;
  1008. gcry_mpi_t *array = NULL;
  1009. *ret_want_pkcs1 = 0;
  1010. *ret_modern = 0;
  1011. /* Check that the first element is valid. */
  1012. list = gcry_sexp_find_token (sexp, "enc-val" , 0);
  1013. if (!list)
  1014. {
  1015. err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object. */
  1016. goto leave;
  1017. }
  1018. l2 = gcry_sexp_nth (list, 1);
  1019. if (!l2)
  1020. {
  1021. err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
  1022. goto leave;
  1023. }
  1024. /* Extract identifier of sublist. */
  1025. name = _gcry_sexp_nth_string (l2, 0);
  1026. if (!name)
  1027. {
  1028. err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
  1029. goto leave;
  1030. }
  1031. if (!strcmp (name, "flags"))
  1032. {
  1033. /* There is a flags element - process it. */
  1034. const char *s;
  1035. int i;
  1036. *ret_modern = 1;
  1037. for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
  1038. {
  1039. s = gcry_sexp_nth_data (l2, i, &n);
  1040. if (! s)
  1041. ; /* Not a data element - ignore. */
  1042. else if (n == 3 && !memcmp (s, "raw", 3))
  1043. ; /* This is just a dummy as it is the default. */
  1044. else if (n == 5 && !memcmp (s, "pkcs1", 5))
  1045. *ret_want_pkcs1 = 1;
  1046. else if (n == 11 && ! memcmp (s, "no-blinding", 11))
  1047. parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
  1048. else
  1049. {
  1050. err = GPG_ERR_INV_FLAG;
  1051. goto leave;
  1052. }
  1053. }
  1054. /* Get the next which has the actual data. */
  1055. gcry_sexp_release (l2);
  1056. l2 = gcry_sexp_nth (list, 2);
  1057. if (!l2)
  1058. {
  1059. err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
  1060. goto leave;
  1061. }
  1062. /* Extract sublist identifier. */
  1063. gcry_free (name);
  1064. name = _gcry_sexp_nth_string (l2, 0);
  1065. if (!name)
  1066. {
  1067. err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
  1068. goto leave;
  1069. }
  1070. gcry_sexp_release (list);
  1071. list = l2;
  1072. l2 = NULL;
  1073. }
  1074. ath_mutex_lock (&pubkeys_registered_lock);
  1075. module = gcry_pk_lookup_name (name);
  1076. ath_mutex_unlock (&pubkeys_registered_lock);
  1077. if (!module)
  1078. {
  1079. err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
  1080. goto leave;
  1081. }
  1082. pubkey = (gcry_pk_spec_t *) module->spec;
  1083. elems = pubkey->elements_enc;
  1084. array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
  1085. if (!array)
  1086. {
  1087. err = gpg_err_code_from_errno (errno);
  1088. goto leave;
  1089. }
  1090. err = sexp_elements_extract (list, elems, array, NULL);
  1091. leave:
  1092. gcry_sexp_release (list);
  1093. gcry_sexp_release (l2);
  1094. gcry_free (name);
  1095. if (err)
  1096. {
  1097. ath_mutex_lock (&pubkeys_registered_lock);
  1098. _gcry_module_release (module);
  1099. ath_mutex_unlock (&pubkeys_registered_lock);
  1100. gcry_free (array);
  1101. }
  1102. else
  1103. {
  1104. *retarray = array;
  1105. *retalgo = module;
  1106. *flags = parsed_flags;
  1107. }
  1108. return err;
  1109. }
  1110. /* Take the hash value and convert into an MPI, suitable for
  1111. passing to the low level functions. We currently support the
  1112. old style way of passing just a MPI and the modern interface which
  1113. allows to pass flags so that we can choose between raw and pkcs1
  1114. padding - may be more padding options later.
  1115. (<mpi>)
  1116. or
  1117. (data
  1118. [(flags [pkcs1])]
  1119. [(hash <algo> <value>)]
  1120. [(value <text>)]
  1121. )
  1122. Either the VALUE or the HASH element must be present for use
  1123. with signatures. VALUE is used for encryption.
  1124. NBITS is the length of the key in bits.
  1125. */
  1126. static gcry_err_code_t
  1127. sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
  1128. int for_encryption, int *flags)
  1129. {
  1130. gcry_err_code_t rc = 0;
  1131. gcry_sexp_t ldata, lhash, lvalue;
  1132. int i;
  1133. size_t n;
  1134. const char *s;
  1135. int is_raw = 0, is_pkcs1 = 0, unknown_flag=0;
  1136. int parsed_flags = 0, dummy_flags;
  1137. if (! flags)
  1138. flags = &dummy_flags;
  1139. *ret_mpi = NULL;
  1140. ldata = gcry_sexp_find_token (input, "data", 0);
  1141. if (!ldata)
  1142. { /* assume old style */
  1143. *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
  1144. return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
  1145. }
  1146. /* see whether there is a flags object */
  1147. {
  1148. gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
  1149. if (lflags)
  1150. { /* parse the flags list. */
  1151. for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
  1152. {
  1153. s = gcry_sexp_nth_data (lflags, i, &n);
  1154. if (!s)
  1155. ; /* not a data element*/
  1156. else if ( n == 3 && !memcmp (s, "raw", 3))
  1157. is_raw = 1;
  1158. else if ( n == 5 && !memcmp (s, "pkcs1", 5))
  1159. is_pkcs1 = 1;
  1160. else if (n == 11 && ! memcmp (s, "no-blinding", 11))
  1161. parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
  1162. else
  1163. unknown_flag = 1;
  1164. }
  1165. gcry_sexp_release (lflags);
  1166. }
  1167. }
  1168. if (!is_pkcs1 && !is_raw)
  1169. is_raw = 1; /* default to raw */
  1170. /* Get HASH or MPI */
  1171. lhash = gcry_sexp_find_token (ldata, "hash", 0);
  1172. lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
  1173. if (!(!lhash ^ !lvalue))
  1174. rc = GPG_ERR_INV_OBJ; /* none or both given */
  1175. else if (unknown_flag)
  1176. rc = GPG_ERR_INV_FLAG;
  1177. else if (is_raw && is_pkcs1 && !for_encryption)
  1178. rc = GPG_ERR_CONFLICT;
  1179. else if (is_raw && lvalue)
  1180. {
  1181. *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
  1182. if (!*ret_mpi)
  1183. rc = GPG_ERR_INV_OBJ;
  1184. }
  1185. else if (is_pkcs1 && lvalue && for_encryption)
  1186. {
  1187. /* Create pkcs#1 block type 2 padding. */
  1188. unsigned char *frame = NULL;
  1189. size_t nframe = (nbits+7) / 8;
  1190. const void * value;
  1191. size_t valuelen;
  1192. unsigned char *p;
  1193. if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
  1194. rc = GPG_ERR_INV_OBJ;
  1195. else if (valuelen + 7 > nframe || !nframe)
  1196. {
  1197. /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
  1198. rc = GPG_ERR_TOO_SHORT; /* the key is too short */
  1199. }
  1200. else if ( !(frame = gcry_malloc_secure (nframe)))
  1201. rc = gpg_err_code_from_errno (errno);
  1202. else
  1203. {
  1204. n = 0;
  1205. frame[n++] = 0;
  1206. frame[n++] = 2; /* block type */
  1207. i = nframe - 3 - valuelen;
  1208. gcry_assert (i > 0);
  1209. p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
  1210. /* Replace zero bytes by new values. */
  1211. for (;;)
  1212. {
  1213. int j, k;
  1214. unsigned char *pp;
  1215. /* Count the zero bytes. */
  1216. for (j=k=0; j < i; j++)
  1217. {
  1218. if (!p[j])
  1219. k++;
  1220. }
  1221. if (!k)
  1222. break; /* Okay: no (more) zero bytes. */
  1223. k += k/128 + 3; /* Better get some more. */
  1224. pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
  1225. for (j=0; j < i && k; )
  1226. {
  1227. if (!p[j])
  1228. p[j] = pp[--k];
  1229. if (p[j])
  1230. j++;
  1231. }
  1232. gcry_free (pp);
  1233. }
  1234. memcpy (frame+n, p, i);
  1235. n += i;
  1236. gcry_free (p);
  1237. frame[n++] = 0;
  1238. memcpy (frame+n, value, valuelen);
  1239. n += valuelen;
  1240. gcry_assert (n == nframe);
  1241. /* FIXME, error checking? */
  1242. gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
  1243. }
  1244. gcry_free(frame);
  1245. }
  1246. else if (is_pkcs1 && lhash && !for_encryption)
  1247. {
  1248. /* Create pkcs#1 block type 1 padding. */
  1249. if (gcry_sexp_length (lhash) != 3)
  1250. rc = GPG_ERR_INV_OBJ;
  1251. else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
  1252. rc = GPG_ERR_INV_OBJ;
  1253. else
  1254. {
  1255. static struct { const char *name; int algo; } hashnames[] =
  1256. { { "sha1", GCRY_MD_SHA1 },
  1257. { "md5", GCRY_MD_MD5 },
  1258. { "sha256", GCRY_MD_SHA256 },
  1259. { "ripemd160", GCRY_MD_RMD160 },
  1260. { "rmd160", GCRY_MD_RMD160 },
  1261. { "sha384", GCRY_MD_SHA384 },
  1262. { "sha512", GCRY_MD_SHA512 },
  1263. { "sha224", GCRY_MD_SHA224 },
  1264. { "md2", GCRY_MD_MD2 },
  1265. { "md4", GCRY_MD_MD4 },
  1266. { "tiger", GCRY_MD_TIGER },
  1267. { "haval", GCRY_MD_HAVAL },
  1268. { NULL, 0 }
  1269. };
  1270. int algo;
  1271. byte asn[100];
  1272. byte *frame = NULL;
  1273. size_t nframe = (nbits+7) / 8;
  1274. const void * value;
  1275. size_t valuelen;
  1276. size_t asnlen, dlen;
  1277. for (i=0; hashnames[i].name; i++)
  1278. {
  1279. if ( strlen (hashnames[i].name) == n
  1280. && !memcmp (hashnames[i].name, s, n))
  1281. break;
  1282. }
  1283. if (hashnames[i].name)
  1284. algo = hashnames[i].algo;
  1285. else
  1286. {
  1287. /* In case of not listed or dynamically allocated hash
  1288. algorithm we fall back to this somewhat slower
  1289. method. Further, it also allows to use OIDs as
  1290. algorithm names. */
  1291. char *tmpname;
  1292. tmpname = gcry_malloc (n+1);
  1293. if (!tmpname)
  1294. algo = 0; /* Out of core - silently give up. */
  1295. else
  1296. {
  1297. memcpy (tmpname, s, n);
  1298. tmpname[n] = 0;
  1299. algo = gcry_md_map_name (tmpname);
  1300. gcry_free (tmpname);
  1301. }
  1302. }
  1303. asnlen = DIM(asn);
  1304. dlen = gcry_md_get_algo_dlen (algo);
  1305. if (!algo)
  1306. rc = GPG_ERR_DIGEST_ALGO;
  1307. else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
  1308. || !valuelen )
  1309. rc = GPG_ERR_INV_OBJ;
  1310. else if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
  1311. {
  1312. /* We don't have yet all of the above algorithms. */
  1313. rc = GPG_ERR_NOT_IMPLEMENTED;
  1314. }
  1315. else if ( valuelen != dlen )
  1316. {
  1317. /* Hash value does not match the length of digest for
  1318. the given algorithm. */
  1319. rc = GPG_ERR_CONFLICT;
  1320. }
  1321. else if( !dlen || dlen + asnlen + 4 > nframe)
  1322. {
  1323. /* Can't encode an DLEN byte digest MD into a NFRAME
  1324. byte frame. */
  1325. rc = GPG_ERR_TOO_SHORT;
  1326. }
  1327. else if ( !(frame = gcry_malloc (nframe)) )
  1328. rc = gpg_err_code_from_errno (errno);
  1329. else
  1330. { /* Assemble the pkcs#1 block type 1. */
  1331. n = 0;
  1332. frame[n++] = 0;
  1333. frame[n++] = 1; /* block type */
  1334. i = nframe - valuelen - asnlen - 3 ;
  1335. gcry_assert (i > 1);
  1336. memset (frame+n, 0xff, i );
  1337. n += i;
  1338. frame[n++] = 0;
  1339. memcpy (frame+n, asn, asnlen);
  1340. n += asnlen;
  1341. memcpy (frame+n, value, valuelen );
  1342. n += valuelen;
  1343. gcry_assert (n == nframe);
  1344. /* Convert it into an MPI. FIXME: error checking? */
  1345. gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
  1346. }
  1347. gcry_free (frame);
  1348. }
  1349. }
  1350. else
  1351. rc = GPG_ERR_CONFLICT;
  1352. gcry_sexp_release (ldata);
  1353. gcry_sexp_release (lhash);
  1354. gcry_sexp_release (lvalue);
  1355. if (!rc)
  1356. *flags = parsed_flags;
  1357. return rc;
  1358. }
  1359. /*
  1360. Do a PK encrypt operation
  1361. Caller has to provide a public key as the SEXP pkey and data as a
  1362. SEXP with just one MPI in it. Alternativly S_DATA might be a
  1363. complex S-Expression, similar to the one used for signature
  1364. verification. This provides a flag which allows to handle PKCS#1
  1365. block type 2 padding. The function returns a a sexp which may be
  1366. passed to to pk_decrypt.
  1367. Returns: 0 or an errorcode.
  1368. s_data = See comment for sexp_data_to_mpi
  1369. s_pkey = <key-as-defined-in-sexp_to_key>
  1370. r_ciph = (enc-val
  1371. (<algo>
  1372. (<param_name1> <mpi>)
  1373. ...
  1374. (<param_namen> <mpi>)
  1375. ))
  1376. */
  1377. gcry_error_t
  1378. gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
  1379. {
  1380. gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
  1381. const char *algo_name, *algo_elems;
  1382. int flags;
  1383. gcry_err_code_t rc;
  1384. gcry_pk_spec_t *pubkey = NULL;
  1385. gcry_module_t module = NULL;
  1386. *r_ciph = NULL;
  1387. REGISTER_DEFAULT_PUBKEYS;
  1388. /* Get the key. */
  1389. rc = sexp_to_key (s_pkey, 0, &pkey, &module);
  1390. if (rc)
  1391. goto leave;
  1392. gcry_assert (module);
  1393. pubkey = (gcry_pk_spec_t *) module->spec;
  1394. /* If aliases for the algorithm name exists, take the first one
  1395. instead of the regular name to adhere to SPKI conventions. We
  1396. assume that the first alias name is the lowercase version of the
  1397. regular one. This change is required for compatibility with
  1398. 1.1.12 generated S-expressions. */
  1399. algo_name = pubkey->aliases? *pubkey->aliases : NULL;
  1400. if (!algo_name || !*algo_name)
  1401. algo_name = pubkey->name;
  1402. algo_elems = pubkey->elements_enc;
  1403. /* Get the stuff we want to encrypt. */
  1404. rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
  1405. &flags);
  1406. if (rc)
  1407. goto leave;
  1408. /* Now we can encrypt DATA to CIPH. */
  1409. ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
  1410. if (!ciph)
  1411. {
  1412. rc = gpg_err_code_from_errno (errno);
  1413. goto leave;
  1414. }
  1415. rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
  1416. mpi_free (data);
  1417. data = NULL;
  1418. if (rc)
  1419. goto leave;
  1420. /* We did it. Now build the return list */
  1421. {
  1422. char *string, *p;
  1423. int i;
  1424. size_t nelem = strlen (algo_elems);
  1425. size_t needed = 19 + strlen (algo_name) + (nelem * 5);
  1426. void **arg_list;
  1427. /* Build the string. */
  1428. string = p = gcry_malloc (needed);
  1429. if (!string)
  1430. {
  1431. rc = gpg_err_code_from_errno (errno);
  1432. goto leave;
  1433. }
  1434. p = stpcpy ( p, "(enc-val(" );
  1435. p = stpcpy ( p, algo_name );
  1436. for (i=0; algo_elems[i]; i++ )
  1437. {
  1438. *p++ = '(';
  1439. *p++ = algo_elems[i];
  1440. p = stpcpy ( p, "%m)" );
  1441. }
  1442. strcpy ( p, "))" );
  1443. /* And now the ugly part: We don't have a function to pass an
  1444. * array to a format string, so we have to do it this way :-(. */
  1445. /* FIXME: There is now such a format specifier, so we can
  1446. change the code to be more clear. */
  1447. arg_list = malloc (nelem * sizeof *arg_list);
  1448. if (!arg_list)
  1449. {
  1450. rc = gpg_err_code_from_errno (errno);
  1451. goto leave;
  1452. }
  1453. for (i = 0; i < nelem; i++)
  1454. arg_list[i] = ciph + i;
  1455. rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
  1456. free (arg_list);
  1457. if (rc)
  1458. BUG ();
  1459. gcry_free (string);
  1460. }
  1461. leave:
  1462. if (pkey)
  1463. {
  1464. release_mpi_array (pkey);
  1465. gcry_free (pkey);
  1466. }
  1467. if (ciph)
  1468. {
  1469. release_mpi_array (ciph);
  1470. gcry_free (ciph);
  1471. }
  1472. if (module)
  1473. {
  1474. ath_mutex_lock (&pubkeys_registered_lock);
  1475. _gcry_module_release (module);
  1476. ath_mutex_unlock (&pubkeys_registered_lock);
  1477. }
  1478. return gcry_error (rc);
  1479. }
  1480. /*
  1481. Do a PK decrypt operation
  1482. Caller has to provide a secret key as the SEXP skey and data in a
  1483. format as created by gcry_pk_encrypt. For historic reasons the
  1484. function returns simply an MPI as an S-expression part; this is
  1485. deprecated and the new method should be used which returns a real
  1486. S-expressionl this is selected by adding at least an empty flags
  1487. list to S_DATA.
  1488. Returns: 0 or an errorcode.
  1489. s_data = (enc-val
  1490. [(flags)]
  1491. (<algo>
  1492. (<param_name1> <mpi>)
  1493. ...
  1494. (<param_namen> <mpi>)
  1495. ))
  1496. s_skey = <key-as-defined-in-sexp_to_key>
  1497. r_plain= Either an incomplete S-expression without the parentheses
  1498. or if the flags list is used (even if empty) a real S-expression:
  1499. (value PLAIN).
  1500. */
  1501. gcry_error_t
  1502. gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
  1503. {
  1504. gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
  1505. int modern, want_pkcs1, flags;
  1506. gcry_err_code_t rc;
  1507. gcry_module_t module_enc = NULL, module_key = NULL;
  1508. gcry_pk_spec_t *pubkey = NULL;
  1509. *r_plain = NULL;
  1510. REGISTER_DEFAULT_PUBKEYS;
  1511. rc = sexp_to_key (s_skey, 1, &skey, &module_key);
  1512. if (rc)
  1513. goto leave;
  1514. rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &want_pkcs1, &flags);
  1515. if (rc)
  1516. goto leave;
  1517. if (module_key->mod_id != module_enc->mod_id)
  1518. {
  1519. rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
  1520. goto leave;
  1521. }
  1522. pubkey = (gcry_pk_spec_t *) module_key->spec;
  1523. rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
  1524. if (rc)
  1525. goto leave;
  1526. if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
  1527. BUG ();
  1528. leave:
  1529. if (skey)
  1530. {
  1531. release_mpi_array (skey);
  1532. gcry_free (skey);
  1533. }
  1534. if (plain)
  1535. mpi_free (plain);
  1536. if (data)
  1537. {
  1538. release_mpi_array (data);
  1539. gcry_free (data);
  1540. }
  1541. if (module_key || module_enc)
  1542. {
  1543. ath_mutex_lock (&pubkeys_registered_lock);
  1544. if (module_key)
  1545. _gcry_module_release (module_key);
  1546. if (module_enc)
  1547. _gcry_module_release (module_enc);
  1548. ath_mutex_unlock (&pubkeys_registered_lock);
  1549. }
  1550. return gcry_error (rc);
  1551. }
  1552. /*
  1553. Create a signature.
  1554. Caller has to provide a secret key as the SEXP skey and data
  1555. expressed as a SEXP list hash with only one element which should
  1556. instantly be available as a MPI. Alternatively the structure given
  1557. below may be used for S_HASH, it provides the abiliy to pass flags
  1558. to the operation; the only flag defined by now is "pkcs1" which
  1559. does PKCS#1 block type 1 style padding.
  1560. Returns: 0 or an errorcode.
  1561. In case of 0 the function returns a new SEXP with the
  1562. signature value; the structure of this signature depends on the
  1563. other arguments but is always suitable to be passed to
  1564. gcry_pk_verify
  1565. s_hash = See comment for sexp_data_to_mpi
  1566. s_skey = <key-as-defined-in-sexp_to_key>
  1567. r_sig = (sig-val
  1568. (<algo>
  1569. (<param_name1> <mpi>)
  1570. ...
  1571. (<param_namen> <mpi>))
  1572. [(hash algo)])
  1573. Note that (hash algo) in R_SIG is not used.
  1574. */
  1575. gcry_error_t
  1576. gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
  1577. {
  1578. gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
  1579. gcry_pk_spec_t *pubkey = NULL;
  1580. gcry_module_t module = NULL;
  1581. const char *algo_name, *algo_elems;
  1582. int i;
  1583. gcry_err_code_t rc;
  1584. *r_sig = NULL;
  1585. REGISTER_DEFAULT_PUBKEYS;
  1586. rc = sexp_to_key (s_skey, 1, &skey, &module);
  1587. if (rc)
  1588. goto leave;
  1589. gcry_assert (module);
  1590. pubkey = (gcry_pk_spec_t *) module->spec;
  1591. algo_name = pubkey->aliases? *pubkey->aliases : NULL;
  1592. if (!algo_name || !*algo_name)
  1593. algo_name = pubkey->name;
  1594. algo_elems = pubkey->elements_sig;
  1595. /* Get the stuff we want to sign. Note that pk_get_nbits does also
  1596. work on a private key. */
  1597. rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
  1598. &hash, 0, NULL);
  1599. if (rc)
  1600. goto leave;
  1601. result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
  1602. if (!result)
  1603. {
  1604. rc = gpg_err_code_from_errno (errno);
  1605. goto leave;
  1606. }
  1607. rc = pubkey_sign (module->mod_id, result, hash, skey);
  1608. if (rc)
  1609. goto leave;
  1610. {
  1611. char *string, *p;
  1612. size_t nelem, needed = strlen (algo_name) + 20;
  1613. void **arg_list;
  1614. nelem = strlen (algo_elems);
  1615. /* Count elements, so that we can allocate enough space. */
  1616. needed += 10 * nelem;
  1617. /* Build the string. */
  1618. string = p = gcry_malloc (needed);
  1619. if (!string)
  1620. {
  1621. rc = gpg_err_code_from_errno (errno);
  1622. goto leave;
  1623. }
  1624. p = stpcpy (p, "(sig-val(");
  1625. p = stpcpy (p, algo_name);
  1626. for (i = 0; algo_elems[i]; i++)
  1627. {
  1628. *p++ = '(';
  1629. *p++ = algo_elems[i];
  1630. p = stpcpy (p, "%m)");
  1631. }
  1632. strcpy (p, "))");
  1633. arg_list = malloc (nelem * sizeof *arg_list);
  1634. if (!arg_list)
  1635. {
  1636. rc = gpg_err_code_from_errno (errno);
  1637. goto leave;
  1638. }
  1639. for (i = 0; i < nelem; i++)
  1640. arg_list[i] = result + i;
  1641. rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
  1642. free (arg_list);
  1643. if (rc)
  1644. BUG ();
  1645. gcry_free (string);
  1646. }
  1647. leave:
  1648. if (skey)
  1649. {
  1650. release_mpi_array (skey);
  1651. gcry_free (skey);
  1652. }
  1653. if (hash)
  1654. mpi_free (hash);
  1655. if (result)
  1656. {
  1657. release_mpi_array (result);
  1658. gcry_free (result);
  1659. }
  1660. return gcry_error (rc);
  1661. }
  1662. /*
  1663. Verify a signature.
  1664. Caller has to supply the public key pkey, the signature sig and his
  1665. hashvalue data. Public key has to be a standard public key given
  1666. as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
  1667. must be an S-Exp like the one in sign too. */
  1668. gcry_error_t
  1669. gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
  1670. {
  1671. gcry_module_t module_key = NULL, module_sig = NULL;
  1672. gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
  1673. gcry_err_code_t rc;
  1674. REGISTER_DEFAULT_PUBKEYS;
  1675. rc = sexp_to_key (s_pkey, 0, &pkey, &module_key);
  1676. if (rc)
  1677. goto leave;
  1678. rc = sexp_to_sig (s_sig, &sig, &module_sig);
  1679. if (rc)
  1680. goto leave;
  1681. /* Fixme: Check that the algorithm of S_SIG is compatible to the one
  1682. of S_PKEY. */
  1683. if (module_key->mod_id != module_sig->mod_id)
  1684. {
  1685. rc = GPG_ERR_CONFLICT;
  1686. goto leave;
  1687. }
  1688. rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
  1689. if (rc)
  1690. goto leave;
  1691. rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
  1692. leave:
  1693. if (pkey)
  1694. {
  1695. release_mpi_array (pkey);
  1696. gcry_free (pkey);
  1697. }
  1698. if (sig)
  1699. {
  1700. release_mpi_array (sig);
  1701. gcry_free (sig);
  1702. }
  1703. if (hash)
  1704. mpi_free (hash);
  1705. if (module_key || module_sig)
  1706. {
  1707. ath_mutex_lock (&pubkeys_registered_lock);
  1708. if (module_key)
  1709. _gcry_module_release (module_key);
  1710. if (module_sig)
  1711. _gcry_module_release (module_sig);
  1712. ath_mutex_unlock (&pubkeys_registered_lock);
  1713. }
  1714. return gcry_error (rc);
  1715. }
  1716. /*
  1717. Test a key.
  1718. This may be used either for a public or a secret key to see whether
  1719. the internal structure is okay.
  1720. Returns: 0 or an errorcode.
  1721. s_key = <key-as-defined-in-sexp_to_key> */
  1722. gcry_error_t
  1723. gcry_pk_testkey (gcry_sexp_t s_key)
  1724. {
  1725. gcry_module_t module = NULL;
  1726. gcry_mpi_t *key = NULL;
  1727. gcry_err_code_t rc;
  1728. REGISTER_DEFAULT_PUBKEYS;
  1729. /* Note we currently support only secret key checking. */
  1730. rc = sexp_to_key (s_key, 1, &key, &module);
  1731. if (! rc)
  1732. {
  1733. rc = pubkey_check_secret_key (module->mod_id, key);
  1734. release_mpi_array (key);
  1735. gcry_free (key);
  1736. }
  1737. return gcry_error (rc);
  1738. }
  1739. /*
  1740. Create a public key pair and return it in r_key.
  1741. How the key is created depends on s_parms:
  1742. (genkey
  1743. (algo
  1744. (parameter_name_1 ....)
  1745. ....
  1746. (parameter_name_n ....)
  1747. ))
  1748. The key is returned in a format depending on the
  1749. algorithm. Both, private and secret keys are returned
  1750. and optionally some additional informatin.
  1751. For elgamal we return this structure:
  1752. (key-data
  1753. (public-key
  1754. (elg
  1755. (p <mpi>)
  1756. (g <mpi>)
  1757. (y <mpi>)
  1758. )
  1759. )
  1760. (private-key
  1761. (elg
  1762. (p <mpi>)
  1763. (g <mpi>)
  1764. (y <mpi>)
  1765. (x <mpi>)
  1766. )
  1767. )
  1768. (misc-key-info
  1769. (pm1-factors n1 n2 ... nn)
  1770. ))
  1771. */
  1772. gcry_error_t
  1773. gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
  1774. {
  1775. gcry_pk_spec_t *pubkey = NULL;
  1776. gcry_module_t module = NULL;
  1777. gcry_sexp_t list = NULL;
  1778. gcry_sexp_t l2 = NULL;
  1779. gcry_sexp_t l3 = NULL;
  1780. char *name = NULL;
  1781. size_t n;
  1782. gcry_err_code_t rc = GPG_ERR_NO_ERROR;
  1783. int i;
  1784. const char *algo_name = NULL;
  1785. int algo;
  1786. const char *sec_elems = NULL, *pub_elems = NULL;
  1787. gcry_mpi_t skey[12];
  1788. gcry_mpi_t *factors = NULL;
  1789. gcry_sexp_t extrainfo = NULL;
  1790. unsigned int nbits = 0;
  1791. unsigned long use_e = 0;
  1792. skey[0] = NULL;
  1793. *r_key = NULL;
  1794. REGISTER_DEFAULT_PUBKEYS;
  1795. list = gcry_sexp_find_token (s_parms, "genkey", 0);
  1796. if (!list)
  1797. {
  1798. rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
  1799. goto leave;
  1800. }
  1801. l2 = gcry_sexp_cadr (list);
  1802. gcry_sexp_release (list);
  1803. list = l2;
  1804. l2 = NULL;
  1805. if (! list)
  1806. {
  1807. rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
  1808. goto leave;
  1809. }
  1810. name = _gcry_sexp_nth_string (list, 0);
  1811. if (!name)
  1812. {
  1813. rc = GPG_ERR_INV_OBJ; /* Algo string missing. */
  1814. goto leave;
  1815. }
  1816. ath_mutex_lock (&pubkeys_registered_lock);
  1817. module = gcry_pk_lookup_name (name);
  1818. ath_mutex_unlock (&pubkeys_registered_lock);
  1819. gcry_free (name);
  1820. name = NULL;
  1821. if (!module)
  1822. {
  1823. rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
  1824. goto leave;
  1825. }
  1826. pubkey = (gcry_pk_spec_t *) module->spec;
  1827. algo = module->mod_id;
  1828. algo_name = pubkey->aliases? *pubkey->aliases : NULL;
  1829. if (!algo_name || !*algo_name)
  1830. algo_name = pubkey->name;
  1831. pub_elems = pubkey->elements_pkey;
  1832. sec_elems = pubkey->elements_skey;
  1833. if (strlen (sec_elems) >= DIM(skey))
  1834. BUG ();
  1835. /* Handle the optional rsa-use-e element. Actually this belong into
  1836. the algorithm module but we have this parameter in the public
  1837. module API, so we need to parse it right here. */
  1838. l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
  1839. if (l2)
  1840. {
  1841. char buf[50];
  1842. const char *s;
  1843. s = gcry_sexp_nth_data (l2, 1, &n);
  1844. if ( !s || n >= DIM (buf) - 1 )
  1845. {
  1846. rc = GPG_ERR_INV_OBJ; /* No value or value too large. */
  1847. goto leave;
  1848. }
  1849. memcpy (buf, s, n);
  1850. buf[n] = 0;
  1851. use_e = strtoul (buf, NULL, 0);
  1852. gcry_sexp_release (l2);
  1853. l2 = NULL;
  1854. }
  1855. else
  1856. use_e = 65537; /* Not given, use the value generated by old versions. */
  1857. /* Get the "nbits" parameter. */
  1858. l2 = gcry_sexp_find_token (list, "nbits", 0);
  1859. if (l2)
  1860. {
  1861. char buf[50];
  1862. const char *s;
  1863. s = gcry_sexp_nth_data (l2, 1, &n);
  1864. if (!s || n >= DIM (buf) - 1 )
  1865. {
  1866. rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr. */
  1867. goto leave;
  1868. }
  1869. memcpy (buf, s, n);
  1870. buf[n] = 0;
  1871. nbits = (unsigned int)strtoul (buf, NULL, 0);
  1872. gcry_sexp_release (l2); l2 = NULL;
  1873. }
  1874. else
  1875. nbits = 0;
  1876. /* Pass control to the algorithm module. */
  1877. rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey,
  1878. &factors, &extrainfo);
  1879. gcry_sexp_release (list); list = NULL;
  1880. if (rc)
  1881. goto leave;
  1882. /* Key generation succeeded: Build an S-expression. */
  1883. {
  1884. char *string, *p;
  1885. size_t nelem=0, nelem_cp = 0, needed=0;
  1886. gcry_mpi_t mpis[30];
  1887. /* Estimate size of format string. */
  1888. nelem = strlen (pub_elems) + strlen (sec_elems);
  1889. if (factors)
  1890. {
  1891. for (i = 0; factors[i]; i++)
  1892. nelem++;
  1893. }
  1894. nelem_cp = nelem;
  1895. needed += nelem * 10;
  1896. /* (+5 is for EXTRAINFO ("%S")). */
  1897. needed += 2 * strlen (algo_name) + 300 + 5;
  1898. if (nelem > DIM (mpis))
  1899. BUG ();
  1900. /* Build the string. */
  1901. nelem = 0;
  1902. string = p = gcry_malloc (needed);
  1903. if (!string)
  1904. {
  1905. rc = gpg_err_code_from_errno (errno);
  1906. goto leave;
  1907. }
  1908. p = stpcpy (p, "(key-data");
  1909. p = stpcpy (p, "(public-key(");
  1910. p = stpcpy (p, algo_name);
  1911. for(i = 0; pub_elems[i]; i++)
  1912. {
  1913. *p++ = '(';
  1914. *p++ = pub_elems[i];
  1915. p = stpcpy (p, "%m)");
  1916. mpis[nelem++] = skey[i];
  1917. }
  1918. p = stpcpy (p, "))");
  1919. p = stpcpy (p, "(private-key(");
  1920. p = stpcpy (p, algo_name);
  1921. for (i = 0; sec_elems[i]; i++)
  1922. {
  1923. *p++ = '(';
  1924. *p++ = sec_elems[i];
  1925. p = stpcpy (p, "%m)");
  1926. mpis[nelem++] = skey[i];
  1927. }
  1928. p = stpcpy (p, "))");
  1929. /* Hack to make release_mpi_array() work. */
  1930. skey[i] = NULL;
  1931. if (extrainfo)
  1932. {
  1933. /* If we have extrainfo we should not have any factors. */
  1934. p = stpcpy (p, "%S");
  1935. }
  1936. else if (factors && factors[0])
  1937. {
  1938. p = stpcpy (p, "(misc-key-info(pm1-factors");
  1939. for(i = 0; factors[i]; i++)
  1940. {
  1941. p = stpcpy (p, "%m");
  1942. mpis[nelem++] = factors[i];
  1943. }
  1944. p = stpcpy (p, "))");
  1945. }
  1946. strcpy (p, ")");
  1947. gcry_assert (p - string < needed);
  1948. while (nelem < DIM (mpis))
  1949. mpis[nelem++] = NULL;
  1950. {
  1951. int elem_n = strlen (pub_elems) + strlen (sec_elems);
  1952. void **arg_list;
  1953. /* Allocate one extra for EXTRAINFO ("%S"). */
  1954. arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
  1955. if (!arg_list)
  1956. {
  1957. rc = gpg_err_code_from_errno (errno);
  1958. goto leave;
  1959. }
  1960. for (i = 0; i < elem_n; i++)
  1961. arg_list[i] = mpis + i;
  1962. if (extrainfo)
  1963. arg_list[i] = &extrainfo;
  1964. else if (factors && factors[0])
  1965. {
  1966. for (; i < nelem_cp; i++)
  1967. arg_list[i] = factors + i - elem_n;
  1968. }
  1969. rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
  1970. gcry_free (arg_list);
  1971. if (rc)
  1972. BUG ();
  1973. gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
  1974. the array gets increased if
  1975. new parameters are added. */
  1976. }
  1977. gcry_free (string);
  1978. }
  1979. leave:
  1980. gcry_free (name);
  1981. gcry_sexp_release (extrainfo);
  1982. release_mpi_array (skey);
  1983. /* Don't free SKEY itself, it is an stack allocated array. */
  1984. if (factors)
  1985. {
  1986. release_mpi_array ( factors );
  1987. gcry_free (factors);
  1988. }
  1989. gcry_sexp_release (l3);
  1990. gcry_sexp_release (l2);
  1991. gcry_sexp_release (list);
  1992. if (module)
  1993. {
  1994. ath_mutex_lock (&pubkeys_registered_lock);
  1995. _gcry_module_release (module);
  1996. ath_mutex_unlock (&pubkeys_registered_lock);
  1997. }
  1998. return gcry_error (rc);
  1999. }
  2000. /*
  2001. Get the number of nbits from the public key.
  2002. Hmmm: Should we have really this function or is it better to have a
  2003. more general function to retrieve different properties of the key? */
  2004. unsigned int
  2005. gcry_pk_get_nbits (gcry_sexp_t key)
  2006. {
  2007. gcry_module_t module = NULL;
  2008. gcry_pk_spec_t *pubkey;
  2009. gcry_mpi_t *keyarr = NULL;
  2010. unsigned int nbits = 0;
  2011. gcry_err_code_t rc;
  2012. REGISTER_DEFAULT_PUBKEYS;
  2013. rc = sexp_to_key (key, 0, &keyarr, &module);
  2014. if (rc == GPG_ERR_INV_OBJ)
  2015. rc = sexp_to_key (key, 1, &keyarr, &module);
  2016. if (rc)
  2017. return 0; /* Error - 0 is a suitable indication for that. */
  2018. pubkey = (gcry_pk_spec_t *) module->spec;
  2019. nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
  2020. ath_mutex_lock (&pubkeys_registered_lock);
  2021. _gcry_module_release (module);
  2022. ath_mutex_unlock (&pubkeys_registered_lock);
  2023. release_mpi_array (keyarr);
  2024. gcry_free (keyarr);
  2025. return nbits;
  2026. }
  2027. /* Return the so called KEYGRIP which is the SHA-1 hash of the public
  2028. key parameters expressed in a way depended on the algorithm.
  2029. ARRAY must either be 20 bytes long or NULL; in the latter case a
  2030. newly allocated array of that size is returned, otherwise ARRAY or
  2031. NULL is returned to indicate an error which is most likely an
  2032. unknown algorithm. The function accepts public or secret keys. */
  2033. unsigned char *
  2034. gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
  2035. {
  2036. gcry_sexp_t list = NULL, l2 = NULL;
  2037. gcry_pk_spec_t *pubkey = NULL;
  2038. gcry_module_t module = NULL;
  2039. pk_extra_spec_t *extraspec;
  2040. const char *s;
  2041. char *name = NULL;
  2042. int idx;
  2043. const char *elems;
  2044. gcry_md_hd_t md = NULL;
  2045. REGISTER_DEFAULT_PUBKEYS;
  2046. /* Check that the first element is valid. */
  2047. list = gcry_sexp_find_token (key, "public-key", 0);
  2048. if (! list)
  2049. list = gcry_sexp_find_token (key, "private-key", 0);
  2050. if (! list)
  2051. list = gcry_sexp_find_token (key, "protected-private-key", 0);
  2052. if (! list)
  2053. list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
  2054. if (! list)
  2055. return NULL; /* No public- or private-key object. */
  2056. l2 = gcry_sexp_cadr (list);
  2057. gcry_sexp_release (list);
  2058. list = l2;
  2059. l2 = NULL;
  2060. name = _gcry_sexp_nth_string (list, 0);
  2061. if (!name)
  2062. goto fail; /* Invalid structure of object. */
  2063. ath_mutex_lock (&pubkeys_registered_lock);
  2064. module = gcry_pk_lookup_name (name);
  2065. ath_mutex_unlock (&pubkeys_registered_lock);
  2066. if (!module)
  2067. goto fail; /* Unknown algorithm. */
  2068. pubkey = (gcry_pk_spec_t *) module->spec;
  2069. extraspec = module->extraspec;
  2070. elems = pubkey->elements_grip;
  2071. if (!elems)
  2072. goto fail; /* No grip parameter. */
  2073. if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
  2074. goto fail;
  2075. if (extraspec && extraspec->comp_keygrip)
  2076. {
  2077. /* Module specific method to compute a keygrip. */
  2078. if (extraspec->comp_keygrip (md, list))
  2079. goto fail;
  2080. }
  2081. else
  2082. {
  2083. /* Generic method to compute a keygrip. */
  2084. for (idx = 0, s = elems; *s; s++, idx++)
  2085. {
  2086. const char *data;
  2087. size_t datalen;
  2088. char buf[30];
  2089. l2 = gcry_sexp_find_token (list, s, 1);
  2090. if (! l2)
  2091. goto fail;
  2092. data = gcry_sexp_nth_data (l2, 1, &datalen);
  2093. if (! data)
  2094. goto fail;
  2095. snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
  2096. gcry_md_write (md, buf, strlen (buf));
  2097. gcry_md_write (md, data, datalen);
  2098. gcry_sexp_release (l2);
  2099. gcry_md_write (md, ")", 1);
  2100. }
  2101. }
  2102. if (!array)
  2103. {
  2104. array = gcry_malloc (20);
  2105. if (! array)
  2106. goto fail;
  2107. }
  2108. memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
  2109. gcry_md_close (md);
  2110. gcry_sexp_release (list);
  2111. return array;
  2112. fail:
  2113. gcry_free (name);
  2114. gcry_sexp_release (l2);
  2115. gcry_md_close (md);
  2116. gcry_sexp_release (list);
  2117. return NULL;
  2118. }
  2119. gcry_error_t
  2120. gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
  2121. {
  2122. gcry_err_code_t err = GPG_ERR_NO_ERROR;
  2123. REGISTER_DEFAULT_PUBKEYS;
  2124. switch (cmd)
  2125. {
  2126. case GCRYCTL_DISABLE_ALGO:
  2127. /* This one expects a buffer pointing to an integer with the
  2128. algo number. */
  2129. if ((! buffer) || (buflen != sizeof (int)))
  2130. err = GPG_ERR_INV_ARG;
  2131. else
  2132. disable_pubkey_algo (*((int *) buffer));
  2133. break;
  2134. default:
  2135. err = GPG_ERR_INV_OP;
  2136. }
  2137. return gcry_error (err);
  2138. }
  2139. /* Return information about the given algorithm
  2140. WHAT selects the kind of information returned:
  2141. GCRYCTL_TEST_ALGO:
  2142. Returns 0 when the specified algorithm is available for use.
  2143. Buffer must be NULL, nbytes may have the address of a variable
  2144. with the required usage of the algorithm. It may be 0 for don't
  2145. care or a combination of the GCRY_PK_USAGE_xxx flags;
  2146. GCRYCTL_GET_ALGO_USAGE:
  2147. Return the usage glafs for the give algo. An invalid alog
  2148. does return 0. Disabled algos are ignored here becuase we
  2149. only want to know whether the algo is at all capable of
  2150. the usage.
  2151. Note: Because this function is in most cases used to return an
  2152. integer value, we can make it easier for the caller to just look at
  2153. the return value. The caller will in all cases consult the value
  2154. and thereby detecting whether a error occured or not (i.e. while
  2155. checking the block size) */
  2156. gcry_error_t
  2157. gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
  2158. {
  2159. gcry_err_code_t err = GPG_ERR_NO_ERROR;
  2160. switch (what)
  2161. {
  2162. case GCRYCTL_TEST_ALGO:
  2163. {
  2164. int use = nbytes ? *nbytes : 0;
  2165. if (buffer)
  2166. err = GPG_ERR_INV_ARG;
  2167. else if (check_pubkey_algo (algorithm, use))
  2168. err = GPG_ERR_PUBKEY_ALGO;
  2169. break;
  2170. }
  2171. case GCRYCTL_GET_ALGO_USAGE:
  2172. {
  2173. gcry_module_t pubkey;
  2174. int use = 0;
  2175. REGISTER_DEFAULT_PUBKEYS;
  2176. ath_mutex_lock (&pubkeys_registered_lock);
  2177. pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  2178. if (pubkey)
  2179. {
  2180. use = ((gcry_pk_spec_t *) pubkey->spec)->use;
  2181. _gcry_module_release (pubkey);
  2182. }
  2183. ath_mutex_unlock (&pubkeys_registered_lock);
  2184. /* FIXME? */
  2185. *nbytes = use;
  2186. break;
  2187. }
  2188. case GCRYCTL_GET_ALGO_NPKEY:
  2189. {
  2190. /* FIXME? */
  2191. int npkey = pubkey_get_npkey (algorithm);
  2192. *nbytes = npkey;
  2193. break;
  2194. }
  2195. case GCRYCTL_GET_ALGO_NSKEY:
  2196. {
  2197. /* FIXME? */
  2198. int nskey = pubkey_get_nskey (algorithm);
  2199. *nbytes = nskey;
  2200. break;
  2201. }
  2202. case GCRYCTL_GET_ALGO_NSIGN:
  2203. {
  2204. /* FIXME? */
  2205. int nsign = pubkey_get_nsig (algorithm);
  2206. *nbytes = nsign;
  2207. break;
  2208. }
  2209. case GCRYCTL_GET_ALGO_NENCR:
  2210. {
  2211. /* FIXME? */
  2212. int nencr = pubkey_get_nenc (algorithm);
  2213. *nbytes = nencr;
  2214. break;
  2215. }
  2216. default:
  2217. err = GPG_ERR_INV_OP;
  2218. }
  2219. return gcry_error (err);
  2220. }
  2221. /* Explicitly initialize this module. */
  2222. gcry_err_code_t
  2223. _gcry_pk_init (void)
  2224. {
  2225. gcry_err_code_t err = GPG_ERR_NO_ERROR;
  2226. REGISTER_DEFAULT_PUBKEYS;
  2227. return err;
  2228. }
  2229. gcry_err_code_t
  2230. _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
  2231. {
  2232. gcry_err_code_t err = GPG_ERR_NO_ERROR;
  2233. gcry_module_t pubkey;
  2234. REGISTER_DEFAULT_PUBKEYS;
  2235. ath_mutex_lock (&pubkeys_registered_lock);
  2236. pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
  2237. if (pubkey)
  2238. *module = pubkey;
  2239. else
  2240. err = GPG_ERR_PUBKEY_ALGO;
  2241. ath_mutex_unlock (&pubkeys_registered_lock);
  2242. return err;
  2243. }
  2244. void
  2245. _gcry_pk_module_release (gcry_module_t module)
  2246. {
  2247. ath_mutex_lock (&pubkeys_registered_lock);
  2248. _gcry_module_release (module);
  2249. ath_mutex_unlock (&pubkeys_registered_lock);
  2250. }
  2251. /* Get a list consisting of the IDs of the loaded pubkey modules. If
  2252. LIST is zero, write the number of loaded pubkey modules to
  2253. LIST_LENGTH and return. If LIST is non-zero, the first
  2254. *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
  2255. according size. In case there are less pubkey modules than
  2256. *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
  2257. gcry_error_t
  2258. gcry_pk_list (int *list, int *list_length)
  2259. {
  2260. gcry_err_code_t err = GPG_ERR_NO_ERROR;
  2261. ath_mutex_lock (&pubkeys_registered_lock);
  2262. err = _gcry_module_list (pubkeys_registered, list, list_length);
  2263. ath_mutex_unlock (&pubkeys_registered_lock);
  2264. return err;
  2265. }
  2266. /* Run the selftests for pubkey algorithm ALGO with optional reporting
  2267. function REPORT. */
  2268. gpg_error_t
  2269. _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
  2270. {
  2271. gcry_module_t module = NULL;
  2272. pk_extra_spec_t *extraspec = NULL;
  2273. gcry_err_code_t ec = 0;
  2274. REGISTER_DEFAULT_PUBKEYS;
  2275. ath_mutex_lock (&pubkeys_registered_lock);
  2276. module = _gcry_module_lookup_id (pubkeys_registered, algo);
  2277. if (module && !(module->flags & FLAG_MODULE_DISABLED))
  2278. extraspec = module->extraspec;
  2279. ath_mutex_unlock (&pubkeys_registered_lock);
  2280. if (extraspec && extraspec->selftest)
  2281. ec = extraspec->selftest (algo, extended, report);
  2282. else
  2283. {
  2284. ec = GPG_ERR_PUBKEY_ALGO;
  2285. if (report)
  2286. report ("pubkey", algo, "module",
  2287. module && !(module->flags & FLAG_MODULE_DISABLED)?
  2288. "no selftest available" :
  2289. module? "algorithm disabled" : "algorithm not found");
  2290. }
  2291. if (module)
  2292. {
  2293. ath_mutex_lock (&pubkeys_registered_lock);
  2294. _gcry_module_release (module);
  2295. ath_mutex_unlock (&pubkeys_registered_lock);
  2296. }
  2297. return gpg_error (ec);
  2298. }
  2299. /* This function is only used by ac.c! */
  2300. gcry_err_code_t
  2301. _gcry_pk_get_elements (int algo, char **enc, char **sig)
  2302. {
  2303. gcry_module_t pubkey;
  2304. gcry_pk_spec_t *spec;
  2305. gcry_err_code_t err;
  2306. char *enc_cp;
  2307. char *sig_cp;
  2308. REGISTER_DEFAULT_PUBKEYS;
  2309. enc_cp = NULL;
  2310. sig_cp = NULL;
  2311. spec = NULL;
  2312. pubkey = _gcry_module_lookup_id (pubkeys_registered, algo);
  2313. if (! pubkey)
  2314. {
  2315. err = GPG_ERR_INTERNAL;
  2316. goto out;
  2317. }
  2318. spec = pubkey->spec;
  2319. if (enc)
  2320. {
  2321. enc_cp = strdup (spec->elements_enc);
  2322. if (! enc_cp)
  2323. {
  2324. err = gpg_err_code_from_errno (errno);
  2325. goto out;
  2326. }
  2327. }
  2328. if (sig)
  2329. {
  2330. sig_cp = strdup (spec->elements_sig);
  2331. if (! sig_cp)
  2332. {
  2333. err = gpg_err_code_from_errno (errno);
  2334. goto out;
  2335. }
  2336. }
  2337. if (enc)
  2338. *enc = enc_cp;
  2339. if (sig)
  2340. *sig = sig_cp;
  2341. err = 0;
  2342. out:
  2343. _gcry_module_release (pubkey);
  2344. if (err)
  2345. {
  2346. free (enc_cp);
  2347. free (sig_cp);
  2348. }
  2349. return err;
  2350. }