├── .classpath ├── .gitignore ├── .project ├── COPYING ├── README.md ├── TODO ├── build.properties ├── build.xml ├── etc ├── SOURCEFOOTER ├── SOURCEHEADER ├── fdc.javadoc.png ├── guardianproject-logo.png ├── overview.html └── sourceforge │ ├── index.html │ └── logobig.gif ├── examples ├── KeySearch.java └── run.sh ├── jni ├── GNUmakefile ├── GnuPGContext.c ├── GnuPGData.c ├── GnuPGGenkeyResult.c ├── GnuPGKey.c ├── GnuPGSignature.c ├── data.h ├── format-code.sh ├── gpgmeutils.c └── gpgmeutils.h ├── pom.xml ├── src └── com │ └── freiheit │ └── gnupg │ ├── GnuPGContext.java │ ├── GnuPGData.java │ ├── GnuPGException.java │ ├── GnuPGGenkeyResult.java │ ├── GnuPGKey.java │ ├── GnuPGPeer.java │ ├── GnuPGSignature.java │ ├── package.html │ └── tests │ └── GnuPGTestSuite.java └── tests ├── android-signing-key.p12 ├── icon-encrypted-not-signed.png.gpg ├── icon.png ├── icon.png.asc ├── icon.png.gpg ├── icon.png.sig ├── one-public-key.pkr ├── public-keys.pkr ├── public-keys.pkr.asc ├── public-keys.pkr.sig ├── pubring.gpg ├── secret ├── secret-keys.skr ├── secret.gpg ├── secring.gpg └── trustdb.gpg /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | build/ 3 | dist/ 4 | hs_err_pid*.log 5 | jni/*.o 6 | jni/*.orig 7 | jni/TAGS 8 | # generated JNI headers 9 | jni/com_freiheit_gnupg_GnuPG*.h 10 | lib/libgnupg-for-java.so 11 | target/ 12 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | gnupg-for-java 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 489 | 490 | Also add information on how to contact you by electronic and paper mail. 491 | 492 | You should also get your employer (if you work as a programmer) or your 493 | school, if any, to sign a "copyright disclaimer" for the library, if 494 | necessary. Here is a sample; alter the names: 495 | 496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker. 498 | 499 | , 1 April 1990 500 | Ty Coon, President of Vice 501 | 502 | That's all there is to it! 503 | 504 | 505 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | GnuPG for Java 2 | ============== 3 | 4 | GnuPG for Java is a Java wrapper for the gpgme (GnuPG Made Easy) library for 5 | working with the GnuPG encryption suite. It is a native binding to the gpgme 6 | using JNI. It requires gpgme 1.4.3 or newer, and expects to work with GnuPG 7 | 2.x as the "engine" in gpgme. With GnuPG 2.x, gpg-agent will handle prompting 8 | the user for the passphrase, as well as passphrase caching. 9 | 10 | gpgpme is the standard library for developing third-party apps on top of GnuPG. 11 | 12 | Stefan Richter originally wrote it for 32-Bit Intel GNU/Linux platforms. Some 13 | of his colleagues added 64-Bit Intel GNU/Linux support. It should build and 14 | run on other UNIX platforms too, but that has not been tested. The Guardian 15 | Project then ported it to GnuPG 2.x and Android as the basis of Gnu Privacy 16 | Guard for Android, and added lots of features and fixed lots of bugs in the 17 | process. 18 | 19 | It should be easy to add Windows support by compiling a DLL, adding this to 20 | the jar and extend the loading mechanism to load a DLL on a Windows platform 21 | instead of loading a .so lib. 22 | 23 | 24 | ## Setup for Building 25 | 26 | You will need a JUnit jar to run the tests. If your system does not provide 27 | one already, you can download the jar and put it into the build/ directory of 28 | this project. 29 | 30 | ### Debian/Ubuntu/Mint/etc 31 | 32 | sudo apt-get install default-jdk make ant build-essential \ 33 | libgpgme11-dev libgpg-error-dev 34 | 35 | 36 | ### Windows 37 | 38 | * Install MinGW (for 32-bit): http://mingw.org/ 39 | * Install Gpg4win: http://gpg4win.org/download.html 40 | ** Signing Key Fingerprint: `61AC 3F5E E4BE 593C 13D6 8B1E 7CBD 620B EC70 B1B8` 41 | 42 | 43 | ### Mac OS X 44 | 45 | You need to install GnuPG2 from one of a couple sources. You can get 46 | it from Homebrew, MacPorts, or Fink. Or you can install 47 | "GPGTools":https://gpgtools.org and then build gpgme from source. 48 | 49 | 50 | ## Building 51 | 52 | To build the `gnupg-for-java.jar` and `libgnupg-for-java.so` in build/, run 53 | this: 54 | 55 | ant clean release 56 | 57 | You can run the test suite using `ant` also: 58 | 59 | ant test 60 | 61 | If you want the optional javadoc in build/docs/, run: 62 | 63 | ant javadoc 64 | 65 | 66 | ## Hacking Notes 67 | 68 | Please conform to our code format standard. For C files use 69 | ./format-code.sh. For Java files, use Eclipse with the Android mode from the 70 | Android project. The default Eclipse formatting is usually close enough. 71 | 72 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | What is missing to complete the first public release? 2 | ----------------------------------------------------- 3 | 4 | MISSING CODE 5 | + Call check_version in static initializer (init_lib) 6 | + Set Locale-Code in static initializer (init_lib) 7 | + Implement destroy-Method and finalizer for GnuPGKey (release_ref...) 8 | + setter/getter for Ascii-Armor 9 | + Search for keys and return GnuPGKey-List (Array...?!) 10 | 11 | - Read complete Key-Structure (all subkeys, all attributes) 12 | 13 | - Password-Entry via Console (take it from henplus) 14 | - Strip spaces from fingerprints 15 | - complete signing code: add_signers to context 16 | - change the access to global env using GetEnv() 17 | 18 | - check for gpg-agent/pinentry and dont require Java-Listener 19 | 20 | - make setField() a utils-function 21 | 22 | [- Synchronize GnuPGContext and GnuPGData for multithreading (and calls to wait())] 23 | 24 | Optional: 25 | [- Make the lib completely stream-based (no large data alloc is required)] 26 | 27 | PROBLEMS/BUGS 28 | - Fix the problems with the passphrase callback (null-Value Passwords etc.) 29 | - Fix all warnings (integer pointer ...) 30 | - Read from InputStream to GnuPGData-Object 31 | - Handle errors, if no key could be retrieved with given fingerprint 32 | - ? 33 | 34 | TESTING 35 | + Check for correct encoding (like special german characters) 36 | + Generate Test-Environment that can be distributed with the code 37 | + Write JUnit-Testcode for all existing methods 38 | - Run tests with large data 39 | [- Use a separate test key-ring (maybe from gpg)] 40 | 41 | VERSION-REQUIREMENTS 42 | - Use seek instead of rewind 43 | - Check for required library 44 | - Check for required jvm version 45 | - Check for required os (must be linux) 46 | 47 | SRC-DISTRIBUTION 48 | + Integrate ant/make compilation parts 49 | - Add LGPL-License and LGPL headers to all files 50 | - Write example code 51 | - Ask, how to transfer license-responsibility to GNU 52 | - Add this as a new SourceForge-Project 53 | 54 | DOCUMENTATION 55 | + Write Javadoc-Comments 56 | - Write Documentation 57 | - Put Documentation as HTML and JavaDoc on SourceForge Project-Page 58 | -------------------------------------------------------------------------------- /build.properties: -------------------------------------------------------------------------------- 1 | # default build.properties 2 | 3 | app.name=gnupg-for-java 4 | app.version=0.2-pre 5 | app.customer=LGPL 6 | app.vendor=freiheit.com technologies gmbh 7 | app.year=2014 8 | 9 | build.compiler=modern 10 | compile.debug=true 11 | compile.deprecation=false 12 | compile.optimize=true 13 | 14 | #where to put etc stuff :-) 15 | etc=etc 16 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 98 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /etc/SOURCEFOOTER: -------------------------------------------------------------------------------- 1 | /* 2 | * Local variables: 3 | * c-basic-offset: 4 4 | * indent-tabs-mode: nil 5 | * compile-command: "ant -emacs -find build.xml" 6 | * End: 7 | */ 8 | -------------------------------------------------------------------------------- /etc/SOURCEHEADER: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: SOURCEHEADER,v 1.1 2005/01/24 13:56:49 stefan Exp $ 3 | * (c) Copyright 2005 freiheit.com technologies gmbh, Germany. 4 | * 5 | * This file is part of Java for GnuPG (http://www.freiheit.com). 6 | * 7 | * Java for GnuPG is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation; either version 2.1 10 | * of the License, or (at your option) any later version. 11 | * 12 | * Please see COPYING for the complete licence. 13 | */ 14 | -------------------------------------------------------------------------------- /etc/fdc.javadoc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/etc/fdc.javadoc.png -------------------------------------------------------------------------------- /etc/guardianproject-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/etc/guardianproject-logo.png -------------------------------------------------------------------------------- /etc/overview.html: -------------------------------------------------------------------------------- 1 | 2 | GnuPG for Java is a (currently GNU/Linux only) GnuPG-library based on the GPGME library. 3 | 4 | GPGME is the standard way to implement language bindings on top of GnuPG. You can use this library 5 | to encrypt, decrypt and sign data and verify signatures on data using an underlying gnupg/gpgme system. 6 |

7 | The key management features are currently not finished. But the library can find/list keys with their signatures. 8 | Future versions will be able to do everything that gpgme can do. 9 |

10 | This library uses JNI (Java Native Interface) to call GPGME-Library functions. Therefore, this library 11 | runs only on platforms for which GPGME is available. Furthermore, this library is tested only under 12 | 32-Bit Intel-based GNU/Linux. 13 |

14 | This is an alpha release. Please expect problems. Although this is working code, this library is not finished and has known and unknown bugs. 15 |

16 | Java for GnuPG is free software; you can redistribute it and/or modify 17 | it under the terms of the GNU Lesser General Public Licenseas published by the Free Software Foundation; either version 2.1 18 | of the License, or (at your option) any later version. 19 |

20 | Please see COPYING in the source distribution for the complete licence. 21 |

22 | So, if you need this library for another platform, if you find a bug or if you need a feature, 23 | please contact Stefan Richter. 24 |

25 | 26 |

27 | Quickstart to encryption: 28 |

29 |


30 |         GnuPGContext ctx = new GnuPGContext();
31 | 
32 |         GnuPGKey[] recipient = new GnuPGKey[1]; 
33 |         recipient[0] = ctx.getKeyByFingerprint("gpg-fingerprint of recipient (must be from your keyring)");
34 |         //attention: fingerprint should not contain spaces...
35 | 
36 |         GnuPGData plain = ctx.createDataObject("I am a secret message.");
37 |         GnuPGData cipher = ctx.createDataObject();//this will contain the cipher after encryption
38 | 
39 |         ctx.encrypt(recipient, plain, cipher);
40 |         System.out.println("Plain text: " + plain);
41 |         System.out.println("Cipher text: " + cipher);
42 |   
43 | 44 | -------------------------------------------------------------------------------- /etc/sourceforge/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | GnuPG for Java project page 5 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |

GnuPG for Java

22 | 23 |

About

24 |

GnuPG for Java is a (currently GNU/Linux only) GnuPG-library based on the GPGME library. GPGME is the standard way to implement language bindings on top of GnuPG. You can use this library to encrypt, decrypt and sign data and verify signatures on data using an underlying gnupg/gpgme system. 25 |
The key management features are currently not finished. But the library can find/list keys with their signatures. Future versions will be able to do everything that gpgme can do. 26 |
This library uses JNI (Java Native Interface) to call GPGME-Library functions. Therefore, this library runs only on platforms for which GPGME is available. Furthermore, this library is tested only under 32-Bit Intel-based GNU/Linux. This is free software under LGPL.

27 | 28 |

News

29 |

24.01.2005
First public alpha release 0.1.2 of GnuPG for Java.

30 | 31 |

Downloads

32 | 46 | 47 |

Discussion

48 | Please use the Sourceforge project forum for discussions about GnuPG for Java. 49 | 50 |
51 |
52 | 53 |
54 | 55 | 56 | -------------------------------------------------------------------------------- /etc/sourceforge/logobig.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/etc/sourceforge/logobig.gif -------------------------------------------------------------------------------- /examples/KeySearch.java: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: KeySearch.java,v 1.1 2005/01/24 13:56:51 stefan Exp $ 3 | * (c) Copyright 2005 freiheit.com technologies gmbh, Germany. 4 | * 5 | * This file is part of Java for GnuPG (http://www.freiheit.com). 6 | * 7 | * Java for GnuPG is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation; either version 2.1 10 | * of the License, or (at your option) any later version. 11 | * 12 | * Please see COPYING for the complete licence. 13 | */ 14 | import com.freiheit.gnupg.*; 15 | 16 | public class KeySearch{ 17 | public static void main(String[] args){ 18 | GnuPGContext ctx = new GnuPGContext(); 19 | GnuPGKey[] keylist; 20 | 21 | if(args != null && args.length == 1){ 22 | keylist = ctx.searchKeys(args[0]); 23 | } 24 | else{ 25 | keylist = ctx.searchKeys(""); 26 | } 27 | 28 | for(GnuPGKey key : keylist){ 29 | System.out.printf("%s\n", key); 30 | } 31 | } 32 | } 33 | /* 34 | * Local variables: 35 | * c-basic-offset: 4 36 | * indent-tabs-mode: nil 37 | * compile-command: "ant -emacs -find build.xml" 38 | * End: 39 | */ 40 | -------------------------------------------------------------------------------- /examples/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | projectroot=`pwd`/.. 4 | 5 | if [ ! -e KeySearch.class ]; then 6 | javac -classpath $projectroot/src KeySearch.java 7 | fi 8 | 9 | java -Djava.library.path=$projectroot/lib \ 10 | -classpath ../build/jar/gnupg-for-java-0.2-pre.jar:. \ 11 | KeySearch 12 | -------------------------------------------------------------------------------- /jni/GNUmakefile: -------------------------------------------------------------------------------- 1 | 2 | JNI_SOURCES := GnuPGContext.c GnuPGData.c GnuPGGenkeyResult.c GnuPGKey.c GnuPGSignature.c 3 | JNI_CLASSES := $(patsubst %.c, com.freiheit.gnupg.%, $(JNI_SOURCES)) 4 | JNI_HEADERS := $(patsubst %.c, com_freiheit_gnupg_%.h, $(JNI_SOURCES)) 5 | SOURCES := $(JNI_SOURCES) gpgmeutils.c 6 | OBJECTS := $(SOURCES:.c=.o) 7 | 8 | DEBUG := -g 9 | ALL_CFLAGS := -Werror -Wall -Wno-deprecated-declarations -fPIC 10 | ALL_CPPFLAGS = -D_REENTRANT -D_THREAD_SAFE -D_FILE_OFFSET_BITS=64 -DLARGEFILE_SOURCE=1 \ 11 | -I"$(JAVA_HOME)/include" 12 | 13 | 14 | # these are provided by ant 15 | ifeq (,$(BUILD_DIR)) 16 | $(error Run the native builds using ant, i.e. `ant gen-jni-library`) 17 | endif 18 | 19 | UNAME := $(shell uname -s) 20 | ifeq (MINGW,$(findstring MINGW,$(UNAME))) 21 | CC := mingw32-gcc 22 | ALL_CFLAGS += -mms-bitfields -Wl,--add-stdcall-alias 23 | ALL_CPPFLAGS += -I"$(JAVA_HOME)/include/win32" -I"$(PROGRAMFILES)/GNU/GnuPG/include" 24 | ALL_LDFLAGS := -s -shared -Wl,--enable-auto-import 25 | ALL_LIBS := -L"$(PROGRAMFILES)/GNU/GnuPG" -lgpgme-11 26 | JAVA_HOME := $(PROGRAMFILES)/Java/jdk1.7.0_51 27 | GNUPG_LIB := $(BUILD_DIR)/gnupg-for-java.dll 28 | else 29 | ifeq ($(UNAME),Darwin) 30 | CC := gcc 31 | ALL_CPPFLAGS += -I/usr/local/MacGPG2/include 32 | ALL_LDFLAGS := -dylib 33 | ALL_LIBS := -L/usr/local/MacGPG2/lib -framework MacGPGME 34 | JAVA_HOME := $(shell /usr/libexec/java_home \ 35 | || echo /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home) 36 | GNUPG_LIB := $(BUILD_DIR)/libgnupg-for-java.dylib 37 | else 38 | CC := gcc 39 | ALL_CFLAGS += $(shell gpgme-config --cflags) 40 | ALL_CPPFLAGS += -I"$(JAVA_HOME)/include/linux" 41 | ALL_LDFLAGS := -shared 42 | ALL_LIBS := $(shell gpgme-config --thread=pthread --libs) 43 | GNUPG_LIB := $(BUILD_DIR)/libgnupg-for-java.so 44 | # to override this JAVA_HOME, use the `-e' flag to make, or call it like: 45 | # make JAVA_HOME=/opt/java 46 | JAVA_HOME := $(shell readlink -f /usr/bin/javac | sed "s:/bin/javac::") 47 | endif 48 | endif 49 | 50 | ALL_CFLAGS := $(ALL_CFLAGS) $(CFLAGS) 51 | ALL_LDFLAGS := $(LDFLAGS) $(ALL_LDFLAGS) 52 | ALL_LIBS := $(LIBS) $(ALL_LIBS) 53 | 54 | 55 | JAVAP := $(JAVA_HOME)/bin/javap 56 | JAVAH := $(JAVA_HOME)/bin/javah 57 | JAVA := $(JAVA_HOME)/bin/java 58 | 59 | INSTALL := install -m 644 60 | 61 | 62 | $(GNUPG_LIB): $(OBJECTS) 63 | $(CC) $(DEBUG) $(ALL_CFLAGS) $(ALL_LDFLAGS) $^ -o $@ $(ALL_LIBS) 64 | 65 | $(OBJECTS): $(JNI_HEADERS) $(SOURCES) gpgmeutils.h 66 | 67 | %.o: %.c 68 | $(CC) $(DEBUG) $(ALL_CFLAGS) $(ALL_CPPFLAGS) -c $< 69 | 70 | lib: $(GNUPG_LIB) 71 | 72 | headers: $(JNI_HEADERS) 73 | 74 | $(JNI_HEADERS): 75 | $(JAVAH) -classpath $(CLASSES_DIR) -jni $(JNI_CLASSES) 76 | 77 | mids: 78 | $(JAVAP) -classpath $(CLASSES_DIR) -s -p $(JNI_CLASSES) 79 | 80 | clean: 81 | rm -f $(OBJECTS) *~ 82 | rm -f $(GNUPG_LIB) 83 | rm -f $(JNI_HEADERS) 84 | 85 | test: 86 | echo "JAVA_HOME: --$(JAVA_HOME)--" 87 | echo "JNI_SOURCES: $(JNI_SOURCES)" 88 | echo "JNI_CLASSES: $(JNI_CLASSES)" 89 | echo "JNI_HEADERS: $(JNI_HEADERS)" 90 | echo "SOURCES: $(SOURCES)" 91 | 92 | TAGS: 93 | etags *.c *.h 94 | 95 | 96 | .PHONY: lib header mids clean test 97 | -------------------------------------------------------------------------------- /jni/GnuPGContext.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include "gpgmeutils.h" 11 | #include "com_freiheit_gnupg_GnuPGContext.h" 12 | 13 | JavaVM* _jvm; 14 | 15 | 16 | JNIEXPORT jint JNICALL 17 | JNI_OnLoad(JavaVM* vm, void* reserved) 18 | { 19 | _jvm = vm; 20 | 21 | // this is required to setup gpgme properly, otherwise it crashes 22 | // https://www.gnupg.org/documentation/manuals/gpgme/Multi-Threading.html 23 | gpgme_check_version("1.5.0"); 24 | 25 | // TODO set locale from the JavaVM's config 26 | setlocale(LC_ALL, ""); 27 | gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); 28 | #ifdef LC_MESSAGES 29 | gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); 30 | #endif 31 | 32 | return JNI_VERSION_1_6; 33 | } 34 | 35 | JNIEXPORT void JNICALL 36 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeGetEngineInfo(JNIEnv* env, jobject self) 37 | { 38 | gpgme_engine_info_t engineInfo; 39 | gpgme_get_engine_info(&engineInfo); 40 | 41 | jclass cls = (*env)->GetObjectClass(env, self); 42 | 43 | UTILS_setStringMember(env, self, cls, "_version", engineInfo->version); 44 | UTILS_setStringMember(env, self, cls, "_filename", engineInfo->file_name); 45 | UTILS_setStringMember(env, self, cls, "_reqversion", 46 | engineInfo->req_version); 47 | UTILS_setIntMember(env, self, cls, "_protocol", engineInfo->protocol); 48 | } 49 | 50 | JNIEXPORT jlong JNICALL 51 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeNew(JNIEnv* env, jobject self) 52 | { 53 | gpgme_ctx_t ctx; 54 | gpgme_new(&ctx); 55 | gpgme_set_armor(ctx, 1); 56 | gpgme_set_textmode(ctx, 1); 57 | gpgme_set_keylist_mode(ctx, GPGME_KEYLIST_MODE_LOCAL); 58 | 59 | return LNG(ctx); 60 | } 61 | 62 | JNIEXPORT void JNICALL 63 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpEncrypt(JNIEnv* env, 64 | jobject self, 65 | jlong context, 66 | jlongArray recipients, 67 | jlong plain, 68 | jlong cipher) 69 | { 70 | gpgme_error_t err; 71 | 72 | //how many keys from recipients did we receive? 73 | jsize len = (*env)->GetArrayLength(env, recipients); 74 | 75 | //allocate a new array with one field larger then number of recipient keys 76 | gpgme_key_t keys[len + 1]; //allowed in C99 Standard...and useful!!! 77 | 78 | // disabled on werners behalf (33% of the work) 79 | // overriden bei sebastian.mangels@freiheit.com, 80 | // we need ascii armor. 81 | //gpgme_set_armor( CONTEXT(context), 0 ); 82 | 83 | if (UTILS_copyRecipientsFromJvm(env, recipients, keys) < 1) { 84 | return; 85 | } 86 | 87 | err = gpgme_data_rewind(DATA(plain)); //TODO: Use seek instead of rewind 88 | if (UTILS_onErrorThrowException(env, err)) { 89 | return; 90 | } 91 | 92 | err = gpgme_data_rewind(DATA(cipher)); //TODO: Use seek instead of rewind 93 | if (UTILS_onErrorThrowException(env, err)) { 94 | return; 95 | } 96 | //call gpgme library function for encryption 97 | err = gpgme_op_encrypt(CONTEXT(context), keys, GPGME_ENCRYPT_ALWAYS_TRUST, 98 | DATA(plain), DATA(cipher)); 99 | if (UTILS_onErrorThrowException(env, err)) { 100 | return; 101 | } 102 | 103 | /* err = gpgme_op_encrypt_start(CONTEXT(context), keys, GPGME_ENCRYPT_ALWAYS_TRUST, (gpgme_data_t)plain, (gpgme_data_t)cipher); */ 104 | /* if(UTILS_onErrorThrowException(env, err)){ */ 105 | /* return; */ 106 | /* } */ 107 | /* gpgme_ctx_t waitedOn = gpgme_wait(CONTEXT(context), err, 1);//HANG UNTIL COMPLETED! */ 108 | /* if(waitedOn != NULL && UTILS_onErrorThrowException(env, err)){ */ 109 | /* return; */ 110 | /* } */ 111 | 112 | } 113 | 114 | JNIEXPORT void JNICALL 115 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpDecrypt(JNIEnv* env, 116 | jobject self, 117 | jlong context, 118 | jlong cipher, 119 | jlong plain) 120 | { 121 | gpgme_error_t err; 122 | 123 | err = gpgme_data_rewind(DATA(cipher)); //TODO: Use seek instead of rewind 124 | if (UTILS_onErrorThrowException(env, err)) { 125 | return; 126 | } 127 | 128 | err = gpgme_data_rewind(DATA(plain)); //TODO: Use seek instead of rewind 129 | if (UTILS_onErrorThrowException(env, err)) { 130 | return; 131 | } 132 | 133 | err = gpgme_op_decrypt(CONTEXT(context), DATA(cipher), DATA(plain)); 134 | if (UTILS_onErrorThrowException(env, err)) { 135 | return; 136 | } 137 | /* err = gpgme_op_decrypt_start(CONTEXT(context), (gpgme_data_t)cipher, (gpgme_data_t)plain); */ 138 | /* if(UTILS_onErrorThrowException(env, err)){ */ 139 | /* return; */ 140 | /* } */ 141 | /* gpgme_ctx_t waitedOn = gpgme_wait(CONTEXT(context), err, 1);//HANG UNTIL COMPLETED! */ 142 | /* if(waitedOn != NULL && UTILS_onErrorThrowException(env, err)){ */ 143 | /* return; */ 144 | /* } */ 145 | } 146 | 147 | static void flush_data(gpgme_data_t dh) 148 | { 149 | char buf[100]; 150 | int ret; 151 | 152 | ret = gpgme_data_seek(dh, 0, SEEK_SET); 153 | 154 | while ((ret = gpgme_data_read(dh, buf, 100)) > 0) 155 | fwrite(buf, ret, 1, stdout); 156 | 157 | } 158 | 159 | 160 | gpgme_error_t 161 | edit_fnc(void* opaque, gpgme_status_code_t status, const char* args, int fd) 162 | { 163 | char* result = NULL; 164 | gpgme_data_t out = (gpgme_data_t)opaque; 165 | 166 | fputs("[-- Response --]\n", stdout); 167 | flush_data(out); 168 | 169 | fprintf(stdout, "[-- Code: %i, %s --]\n", status, args); 170 | 171 | if (fd >= 0) { 172 | if (!strcmp(args, "keyedit.prompt")) { 173 | static int switcher = 0; 174 | 175 | if (!switcher) { 176 | result = "passwd"; 177 | switcher++; 178 | } else { 179 | result = "save"; 180 | switcher--; 181 | } 182 | 183 | } else if (!strcmp(args, "keyedit.save.okay")) { 184 | result = "Y"; 185 | } else if (!strcmp(args, "keygen.valid")) { 186 | result = "0"; 187 | } else if (!strcmp(args, "change_passwd.empty.okay")) { 188 | result = "N"; 189 | } 190 | } 191 | 192 | if (result) { 193 | fprintf(stdout, "[-- Command: %s --]\n", result); 194 | write(fd, result, strlen(result)); 195 | write(fd, "\n", 1); 196 | } 197 | return 0; 198 | } 199 | 200 | 201 | 202 | JNIEXPORT void JNICALL 203 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpChangePassphrase(JNIEnv* env, 204 | jobject self, 205 | jlong context, 206 | jlong keydata) 207 | { 208 | gpgme_error_t err; 209 | 210 | err = gpgme_op_passwd(CONTEXT(context), KEY(keydata), 0); 211 | if (UTILS_onErrorThrowException(env, err)) { 212 | return; 213 | } 214 | } 215 | 216 | JNIEXPORT void JNICALL 217 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeRelease(JNIEnv* env, 218 | jobject self, 219 | jlong context) 220 | { 221 | gpgme_release(CONTEXT(context)); 222 | } 223 | 224 | JNIEXPORT void JNICALL 225 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpEncryptSign(JNIEnv* env, 226 | jobject self, 227 | jlong context, 228 | jlongArray recipients, 229 | jlong plain, 230 | jlong cipher) 231 | { 232 | gpgme_error_t err; 233 | 234 | jsize len = (*env)->GetArrayLength(env, recipients); 235 | gpgme_key_t keys[len + 1]; 236 | if (UTILS_copyRecipientsFromJvm(env, recipients, keys) < 1) { 237 | return; 238 | } 239 | 240 | err = gpgme_data_rewind(DATA(plain)); //TODO: Use seek instead of rewind 241 | if (UTILS_onErrorThrowException(env, err)) { 242 | return; 243 | } 244 | 245 | err = gpgme_data_rewind(DATA(cipher)); //TODO: Use seek instead of rewind 246 | if (UTILS_onErrorThrowException(env, err)) { 247 | return; 248 | } 249 | 250 | err = gpgme_op_encrypt_sign(CONTEXT(context), keys, 251 | GPGME_ENCRYPT_ALWAYS_TRUST, DATA(plain), 252 | DATA(cipher)); 253 | if (UTILS_onErrorThrowException(env, err)) { 254 | return; 255 | } 256 | /* err = gpgme_op_encrypt_sign_start(CONTEXT(context), keys, GPGME_ENCRYPT_ALWAYS_TRUST, (gpgme_data_t)plain, (gpgme_data_t)cipher); */ 257 | /* if(UTILS_onErrorThrowException(env, err)){ */ 258 | /* return; */ 259 | /* } */ 260 | /* gpgme_ctx_t waitedOn = gpgme_wait(CONTEXT(context), err, 1);//HANG UNTIL COMPLETED! */ 261 | /* if(waitedOn != NULL && UTILS_onErrorThrowException(env, err)){ */ 262 | /* return; */ 263 | /* } */ 264 | } 265 | 266 | JNIEXPORT void JNICALL 267 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpDecryptVerify(JNIEnv* env, 268 | jobject self, 269 | jlong context, 270 | jlong cipher, 271 | jlong plain) 272 | { 273 | gpgme_error_t err; 274 | 275 | err = gpgme_data_rewind(DATA(cipher)); //TODO: Use seek instead of rewind 276 | if (UTILS_onErrorThrowException(env, err)) { 277 | return; 278 | } 279 | 280 | err = gpgme_data_rewind(DATA(plain)); //TODO: Use seek instead of rewind 281 | if (UTILS_onErrorThrowException(env, err)) { 282 | return; 283 | } 284 | 285 | err = gpgme_op_decrypt_verify(CONTEXT(context), DATA(cipher), DATA(plain)); 286 | if (UTILS_onErrorThrowException(env, err)) { 287 | return; 288 | } 289 | /* err = gpgme_op_decrypt_verify_start(CONTEXT(context), (gpgme_data_t)cipher, (gpgme_data_t)plain); */ 290 | /* if(UTILS_onErrorThrowException(env, err)){ */ 291 | /* return; */ 292 | /* } */ 293 | /* gpgme_ctx_t waitedOn = gpgme_wait(CONTEXT(context), err, 1);//HANG UNTIL COMPLETED! */ 294 | /* if(waitedOn != NULL && UTILS_onErrorThrowException(env, err)){ */ 295 | /* return; */ 296 | /* } */ 297 | } 298 | 299 | JNIEXPORT void JNICALL 300 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpSign(JNIEnv* env, 301 | jobject self, 302 | jlong context, 303 | jlong plain, 304 | jlong signature) 305 | { 306 | gpgme_error_t err; 307 | 308 | err = gpgme_data_rewind(DATA(plain)); //TODO: Use seek instead of rewind 309 | if (UTILS_onErrorThrowException(env, err)) { 310 | return; 311 | } 312 | 313 | err = gpgme_data_rewind(DATA(signature)); //TODO: Use seek instead of rewind 314 | if (UTILS_onErrorThrowException(env, err)) { 315 | return; 316 | } 317 | 318 | err = gpgme_op_sign(CONTEXT(context), DATA(plain), DATA(signature), 319 | GPGME_SIG_MODE_CLEAR); 320 | if (UTILS_onErrorThrowException(env, err)) { 321 | return; 322 | } 323 | /* err = gpgme_op_sign_start(CONTEXT(context), (gpgme_data_t)plain, (gpgme_data_t)signature, GPGME_SIG_MODE_NORMAL); */ 324 | /* if(UTILS_onErrorThrowException(env, err)){ */ 325 | /* return; */ 326 | /* } */ 327 | 328 | /* gpgme_ctx_t waitedOn = gpgme_wait(CONTEXT(context), err, 0); */ 329 | /* if(waitedOn != NULL && UTILS_onErrorThrowException(env, err)){ */ 330 | /* return; */ 331 | /* } */ 332 | 333 | } 334 | 335 | JNIEXPORT void JNICALL 336 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpVerify(JNIEnv* env, 337 | jobject self, 338 | jlong context, 339 | jlong signature, 340 | jlong signedtxt, 341 | jlong plain) 342 | { 343 | gpgme_error_t err; 344 | 345 | err = gpgme_data_rewind(DATA(signature)); //TODO: Use seek instead of rewind 346 | if (UTILS_onErrorThrowException(env, err)) { 347 | return; 348 | } 349 | 350 | err = gpgme_data_rewind(DATA(signedtxt)); //TODO: Use seek instead of rewind 351 | if (UTILS_onErrorThrowException(env, err)) { 352 | return; 353 | } 354 | 355 | err = gpgme_data_rewind(DATA(plain)); //TODO: Use seek instead of rewind 356 | if (UTILS_onErrorThrowException(env, err)) { 357 | return; 358 | } 359 | 360 | err = gpgme_op_verify(CONTEXT(context), DATA(signature), DATA(signedtxt), 361 | DATA(plain)); 362 | if (UTILS_onErrorThrowException(env, err)) { 363 | return; 364 | } 365 | /* err = gpgme_op_verify_start(CONTEXT(context), (gpgme_data_t)signature, (gpgme_data_t)signedtxt, (gpgme_data_t)plain); */ 366 | /* if(UTILS_onErrorThrowException(env, err)){ */ 367 | /* return; */ 368 | /* } */ 369 | /* gpgme_ctx_t waitedOn = gpgme_wait(CONTEXT(context), err, 0); */ 370 | /* if(waitedOn != NULL && UTILS_onErrorThrowException(env, err)){ */ 371 | /* return; */ 372 | /* } */ 373 | } 374 | 375 | JNIEXPORT jobjectArray JNICALL 376 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeKeylist(JNIEnv* env, 377 | jobject self, 378 | jlong context, 379 | jstring query, 380 | jboolean secret_only) 381 | { 382 | //copy string object from java to native string 383 | const jsize query_len = (*env)->GetStringLength(env, query); 384 | const jbyte* query_str = (jbyte*)(*env)->GetStringUTFChars(env, query, 385 | NULL); 386 | //get the right constructor to invoke for every key in result set 387 | jclass keyClass; 388 | keyClass = (*env)->FindClass(env, "com/freiheit/gnupg/GnuPGKey"); 389 | if (keyClass == NULL) { 390 | return NULL; 391 | } 392 | jmethodID cid; 393 | //get the constructor, that accepts a long as param (that is a ptr to a key).. 394 | cid = (*env)->GetMethodID(env, keyClass, "", "(J)V"); 395 | if (cid == NULL) { 396 | return NULL; 397 | } 398 | 399 | gpgme_error_t err = gpgme_op_keylist_start(CONTEXT(context), 400 | query_len > 0 ? (const char*)query_str : NULL, secret_only); 401 | if (UTILS_onErrorThrowException(env, err)) { 402 | (*env)->ReleaseStringUTFChars(env, query, (const char*)query_str); 403 | return NULL; 404 | } 405 | 406 | gpgme_key_t key; 407 | jlong num_keys_found = 0; 408 | struct _keyInList { 409 | gpgme_key_t key; 410 | struct _keyInList* next; 411 | }; 412 | typedef struct _keyInList* keyInList; 413 | keyInList current, next, head = NULL; 414 | while (!err) { 415 | err = gpgme_op_keylist_next(CONTEXT(context), &key); 416 | if ((gpg_err_code(err) != GPG_ERR_EOF) 417 | && UTILS_onErrorThrowException(env, err)) { 418 | return NULL; 419 | } else if (err) { 420 | break; // we have nothing, quit before setting the list 421 | } 422 | current = (keyInList)malloc(sizeof(keyInList)); 423 | current->key = key; 424 | current->next = head; 425 | head = current; 426 | num_keys_found++; 427 | } 428 | current = head; 429 | jobject keyObj = NULL; 430 | jobjectArray result = (*env)->NewObjectArray(env, 431 | num_keys_found, 432 | keyClass, 433 | NULL); 434 | int i; 435 | for (i = 0; i < num_keys_found; i++) { 436 | key = current->key; 437 | keyObj = (*env)->NewObject(env, keyClass, cid, LNG(key)); 438 | (*env)->SetObjectArrayElement(env, result, i, keyObj); 439 | next = current->next; 440 | free(current); 441 | current = next; 442 | } 443 | 444 | //..and release the query string for gc.. 445 | (*env)->ReleaseStringUTFChars(env, query, (const char*) query_str); 446 | 447 | return result; 448 | } 449 | 450 | JNIEXPORT void JNICALL 451 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeAddSigners(JNIEnv* env, 452 | jobject self, 453 | jlong context, 454 | jlong key) 455 | { 456 | gpgme_error_t err; 457 | err = gpgme_signers_add(CONTEXT(context), KEY(key)); 458 | if (UTILS_onErrorThrowException(env, err)) { 459 | return; 460 | } 461 | } 462 | 463 | JNIEXPORT void JNICALL 464 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeClearSigners(JNIEnv* env, 465 | jobject self, 466 | jlong context) 467 | { 468 | gpgme_signers_clear(CONTEXT(context)); 469 | } 470 | 471 | JNIEXPORT jlong JNICALL 472 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeGetSigner(JNIEnv* env, 473 | jobject self, 474 | jlong context, 475 | jint index) 476 | { 477 | gpgme_key_t key = gpgme_signers_enum(CONTEXT(context), index); 478 | return LNG(key); 479 | } 480 | 481 | JNIEXPORT jlong JNICALL 482 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeGetSignersLength(JNIEnv* env, 483 | jobject self, 484 | jlong context) 485 | { 486 | return (gpgme_signers_count(CONTEXT(context))); 487 | } 488 | 489 | void check_result(gpgme_import_result_t result, char* fpr, int secret) 490 | { 491 | //TODO: Throw exception for possible errors... 492 | if (result->considered != 1) { 493 | fprintf(stderr, "Unexpected number of considered keys %i\n", 494 | result->considered); 495 | } 496 | 497 | if (result->no_user_id != 0) { 498 | fprintf(stderr, "Unexpected number of user ids %i\n", 499 | result->no_user_id); 500 | } 501 | 502 | if ((secret && result->imported != 0) 503 | || (!secret && (result->imported != 0 && result->imported != 1))) { 504 | fprintf(stderr, "Unexpected number of imported keys %i\n", 505 | result->imported); 506 | } 507 | 508 | if (result->imported_rsa != 0) { 509 | fprintf(stderr, "Unexpected number of imported RSA keys %i\n", 510 | result->imported_rsa); 511 | } 512 | 513 | if ((secret && result->unchanged != 0) 514 | || (!secret && ((result->imported == 0 && result->unchanged != 1) 515 | || (result->imported == 1 && result->unchanged != 0)))) { 516 | fprintf(stderr, "Unexpected number of unchanged keys %i\n", 517 | result->unchanged); 518 | } 519 | 520 | if (result->new_user_ids != 0) { 521 | fprintf(stderr, "Unexpected number of new user IDs %i\n", 522 | result->new_user_ids); 523 | } 524 | 525 | if (result->new_sub_keys != 0) { 526 | fprintf(stderr, "Unexpected number of new sub keys %i\n", 527 | result->new_sub_keys); 528 | } 529 | 530 | if ((secret 531 | && ((result->secret_imported == 0 && result->new_signatures != 0) 532 | || (result->secret_imported == 1 && result->new_signatures > 1))) 533 | || (!secret && result->new_signatures != 0)) { 534 | fprintf(stderr, "Unexpected number of new signatures %i\n", 535 | result->new_signatures); 536 | if (result->new_signatures == 2) { 537 | fprintf(stderr, "### ignored due to gpg 1.3.4 problems\n"); 538 | } else { 539 | //exit (1); 540 | } 541 | } 542 | 543 | if (result->new_revocations != 0) { 544 | fprintf(stderr, "Unexpected number of new revocations %i\n", 545 | result->new_revocations); 546 | } 547 | 548 | if ((secret && result->secret_read != 1) 549 | || (!secret && result->secret_read != 0)) { 550 | fprintf(stderr, "Unexpected number of secret keys read %i\n", 551 | result->secret_read); 552 | } 553 | 554 | if ((secret && result->secret_imported != 0 && result->secret_imported != 1) 555 | || (!secret && result->secret_imported != 0)) { 556 | fprintf(stderr, "Unexpected number of secret keys imported %i\n", 557 | result->secret_imported); 558 | } 559 | 560 | if ((secret 561 | && ((result->secret_imported == 0 && result->secret_unchanged != 1) 562 | || (result->secret_imported == 1 563 | && result->secret_unchanged != 0))) 564 | || (!secret && result->secret_unchanged != 0)) { 565 | fprintf(stderr, "Unexpected number of secret keys unchanged %i\n", 566 | result->secret_unchanged); 567 | } 568 | 569 | if (result->not_imported != 0) { 570 | fprintf(stderr, "Unexpected number of secret keys not imported %i\n", 571 | result->not_imported); 572 | } 573 | 574 | if (secret) { 575 | if (!result->imports 576 | || (result->imports->next && result->imports->next->next)) { 577 | fprintf(stderr, "Unexpected number of status reports\n"); 578 | } 579 | } else if (!result->imports || result->imports->next) { 580 | fprintf(stderr, "Unexpected number of status reports\n"); 581 | } 582 | 583 | if (strcmp(fpr, result->imports->fpr)) { 584 | fprintf(stderr, "Unexpected fingerprint %s\n", result->imports->fpr); 585 | } 586 | 587 | if (result->imports->next && strcmp(fpr, result->imports->next->fpr)) { 588 | fprintf(stderr, "Unexpected fingerprint on second status %s\n", 589 | result->imports->next->fpr); 590 | } 591 | 592 | if (result->imports->result != 0) { 593 | fprintf(stderr, "Unexpected status result %s\n", 594 | gpgme_strerror(result->imports->result)); 595 | } 596 | 597 | if (secret) { 598 | if (result->secret_imported == 0) { 599 | if (result->imports->status != GPGME_IMPORT_SECRET) { 600 | fprintf(stderr, "Unexpected status %i\n", 601 | result->imports->status); 602 | } 603 | } else if (result->imports->status 604 | != (GPGME_IMPORT_SECRET | GPGME_IMPORT_NEW) 605 | || (result->imports->next 606 | && result->imports->next->status != GPGME_IMPORT_SIG)) { 607 | fprintf(stderr, "Unexpected status %i\n", result->imports->status); 608 | } 609 | } else if ((result->imported == 0 && result->imports->status != 0) 610 | || (result->imported == 1 611 | && result->imports->status != GPGME_IMPORT_NEW)) { 612 | fprintf(stderr, "Unexpected status %i\n", result->imports->status); 613 | } 614 | } 615 | 616 | JNIEXPORT void JNICALL 617 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpImport(JNIEnv* env, 618 | jobject self, 619 | jlong context, 620 | jlong keydata) 621 | { 622 | gpgme_error_t err; 623 | gpgme_import_result_t result; 624 | 625 | err = gpgme_data_rewind(DATA(keydata)); //TODO: Use seek instead of rewind 626 | if (UTILS_onErrorThrowException(env, err)) { 627 | return; 628 | } 629 | 630 | err = gpgme_op_import(CONTEXT(context), DATA(keydata)); 631 | if (UTILS_onErrorThrowException(env, err)) { 632 | return; 633 | } 634 | result = gpgme_op_import_result(CONTEXT(context)); 635 | if (result == NULL) { 636 | if (UTILS_onErrorThrowException(env, GPG_ERR_NO_PUBKEY)) 637 | return; 638 | } else if (result->imported != 1 || result->not_imported != 0) { 639 | if (result->imports == NULL) { 640 | if (UTILS_onErrorThrowException(env, GPG_ERR_UNUSABLE_PUBKEY)) { 641 | return; 642 | } 643 | } else { 644 | if (UTILS_onErrorThrowException(env, result->imports->result)) { 645 | return; 646 | } 647 | } 648 | } 649 | //TODO: Check result and throw exceptions 650 | //check_result (result, "ADAB7FCC1F4DE2616ECFA402AF82244F9CD9FD55", 0); 651 | } 652 | 653 | JNIEXPORT jboolean JNICALL 654 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeGetArmor(JNIEnv* env, 655 | jobject self, 656 | jlong context) 657 | { 658 | return (jboolean) gpgme_get_armor(CONTEXT(context)); 659 | } 660 | 661 | JNIEXPORT void JNICALL 662 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeSetArmor(JNIEnv* env, 663 | jobject self, 664 | jlong context, 665 | jboolean armor_state) 666 | { 667 | gpgme_set_armor(CONTEXT(context), (int) armor_state); 668 | } 669 | 670 | JNIEXPORT jboolean JNICALL 671 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeGetTextmode(JNIEnv* env, 672 | jobject self, 673 | jlong context) 674 | { 675 | return (jboolean) gpgme_get_textmode(CONTEXT(context)); 676 | } 677 | 678 | JNIEXPORT void JNICALL 679 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeSetTextmode(JNIEnv* env, 680 | jobject self, 681 | jlong context, 682 | jboolean mode) 683 | { 684 | gpgme_set_textmode(CONTEXT(context), (int) mode); 685 | } 686 | 687 | JNIEXPORT void JNICALL 688 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpGenKey(JNIEnv* env, 689 | jobject self, 690 | jlong context, 691 | jstring params) 692 | { 693 | 694 | gpgme_ctx_t ctx = CONTEXT(context); 695 | char* p; 696 | gpgme_error_t err; 697 | 698 | p = (char*)(*env)->GetStringUTFChars(env, params, NULL); 699 | 700 | fprintf(stderr, "genKey: \"%s\"\n", p); 701 | 702 | err = gpgme_op_genkey(ctx, p, NULL, NULL); 703 | 704 | (*env)->ReleaseStringUTFChars(env, params, p); 705 | 706 | if (UTILS_onErrorThrowException(env, err)) { 707 | return; 708 | } 709 | 710 | } 711 | 712 | 713 | JNIEXPORT void JNICALL 714 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpExport(JNIEnv* env, 715 | jobject self, 716 | jlong context, 717 | jstring pattern, 718 | jlong reserved, 719 | jlong keydata) 720 | { 721 | 722 | gpgme_ctx_t ctx = CONTEXT(context); 723 | char* p; 724 | gpgme_data_t data = DATA(keydata); 725 | gpgme_error_t err; 726 | 727 | 728 | p = (char*)(*env)->GetStringUTFChars(env, pattern, NULL); 729 | err = gpgme_op_export(ctx, p, 0, data); 730 | if (UTILS_onErrorThrowException(env, err)) { 731 | return; 732 | } 733 | (*env)->ReleaseStringUTFChars(env, pattern, p); 734 | } 735 | 736 | JNIEXPORT void JNICALL 737 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeCtxSetEngineInfo(JNIEnv* env, 738 | jobject self, 739 | jlong ctx, 740 | jint proto, 741 | jstring fileName, 742 | jstring homeDir) 743 | { 744 | 745 | gpgme_ctx_t context = CONTEXT(ctx); 746 | gpgme_protocol_t protocol = (gpgme_protocol_t) proto; 747 | char* file_name; 748 | char* home_dir; 749 | gpgme_error_t err; 750 | 751 | file_name = (char*)(*env)->GetStringUTFChars(env, fileName, NULL); 752 | home_dir = (char*)(*env)->GetStringUTFChars(env, homeDir, NULL); 753 | 754 | 755 | /*fprintf(stderr, "set engine info: proto: %d, fileName: %s, homeDir: %s\n", proto, file_name, home_dir);*/ 756 | err = gpgme_ctx_set_engine_info(context, protocol, file_name, home_dir); 757 | 758 | (*env)->ReleaseStringUTFChars(env, fileName, file_name); 759 | (*env)->ReleaseStringUTFChars(env, homeDir, home_dir); 760 | 761 | if (UTILS_onErrorThrowException(env, err)) { 762 | return; 763 | } 764 | 765 | } 766 | 767 | 768 | JNIEXPORT jobject JNICALL 769 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpGenkeyResult(JNIEnv* env, 770 | jobject self, 771 | jlong ctx) 772 | { 773 | 774 | gpgme_ctx_t context = CONTEXT(ctx); 775 | gpgme_genkey_result_t result = gpgme_op_genkey_result(context); 776 | jobject resultObj; 777 | 778 | if (result == NULL) { 779 | return NULL; 780 | } 781 | //get the right constructor to invoke for every key in result set 782 | jclass resultClass; 783 | resultClass = 784 | (*env)->FindClass(env, "com/freiheit/gnupg/GnuPGGenkeyResult"); 785 | 786 | if (resultClass == NULL) { 787 | return NULL; 788 | } 789 | 790 | jmethodID cid; 791 | cid = (*env)->GetMethodID(env, resultClass, "", "()V"); 792 | if (cid == NULL) { 793 | return NULL; 794 | } 795 | 796 | resultObj = (*env)->NewObject(env, resultClass, cid); 797 | 798 | UTILS_setStringMember(env, resultObj, resultClass, "_fpr", result->fpr); 799 | UTILS_setBooleanMember(env, resultObj, resultClass, "_primary", 800 | result->primary); 801 | UTILS_setBooleanMember(env, resultObj, resultClass, "_sub", result->sub); 802 | 803 | return resultObj; 804 | } 805 | 806 | JNIEXPORT void JNICALL 807 | Java_com_freiheit_gnupg_GnuPGContext_gpgmeOpDelete(JNIEnv* env, 808 | jobject self, 809 | jlong ctx, 810 | jlong key, 811 | jboolean allowSecret) 812 | { 813 | 814 | gpgme_ctx_t context = CONTEXT(ctx); 815 | gpgme_key_t deletekey = KEY(key); 816 | unsigned int sec = (unsigned int) allowSecret; 817 | gpgme_error_t err; 818 | 819 | 820 | err = gpgme_op_delete(context, deletekey, sec); 821 | 822 | if (UTILS_onErrorThrowException(env, err)) { 823 | return; 824 | } 825 | } 826 | 827 | /* 828 | * Local Variables: 829 | * tab-width: 4; 830 | * c-basic-offset: 4; 831 | * c-file-style: k&r; 832 | * indent-tabs-mode: nil; 833 | * End: 834 | */ 835 | -------------------------------------------------------------------------------- /jni/GnuPGData.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "gpgmeutils.h" 6 | #include "com_freiheit_gnupg_GnuPGData.h" 7 | 8 | // TODO, this is a private header, figure out public techniques... 9 | #include "data.h" 10 | 11 | #define BUFSIZE 1024 12 | 13 | 14 | JNIEXPORT jsize JNICALL 15 | Java_com_freiheit_gnupg_GnuPGData_gpgmeSize(JNIEnv* env, jobject self, jlong data) 16 | { 17 | return (jsize)(DATA(data))->data.mem.size; 18 | } 19 | 20 | JNIEXPORT jlong JNICALL 21 | Java_com_freiheit_gnupg_GnuPGData_gpgmeDataNewFromMem(JNIEnv* env, 22 | jobject self, 23 | jbyteArray plain) 24 | { 25 | gpgme_error_t err; 26 | 27 | jbyte* plain_ptr = (*env)->GetByteArrayElements(env, plain, NULL); //GETMEM(0) 28 | if (plain_ptr == NULL) { 29 | fprintf(stderr, "could not allocate memory.\n"); 30 | return 0; 31 | } 32 | 33 | gpgme_data_t data; 34 | jlong len = (*env)->GetArrayLength(env, plain); 35 | 36 | //make private copy of data 37 | err = gpgme_data_new_from_mem(&data, (const char*) plain_ptr, 38 | (size_t) len, 1); 39 | if (UTILS_onErrorThrowException(env, err)) { 40 | return LNG(NULL); 41 | } 42 | 43 | (*env)->ReleaseByteArrayElements(env, plain, plain_ptr, 0); //RELMEM(0) 44 | jlong result = LNG(data); 45 | return result; 46 | } 47 | 48 | JNIEXPORT jlong JNICALL 49 | Java_com_freiheit_gnupg_GnuPGData_gpgmeDataNewFromFilename(JNIEnv* env, 50 | jobject self, 51 | jstring filename, 52 | jstring mode) 53 | { 54 | const char* mode_str = (*env)->GetStringUTFChars(env, mode, NULL); 55 | const char* filename_str = (*env)->GetStringUTFChars(env, filename, NULL); 56 | if (filename_str == NULL) { 57 | fprintf(stderr, "could not allocate memory.\n"); 58 | return 0; 59 | } 60 | 61 | gpgme_data_t data; 62 | FILE* stream = fopen(filename_str, mode_str); 63 | gpgme_error_t err = gpgme_data_new_from_stream(&data, stream); 64 | if (UTILS_onErrorThrowException(env, err)) { 65 | return LNG(NULL); 66 | } 67 | 68 | (*env)->ReleaseStringUTFChars(env, filename, filename_str); 69 | (*env)->ReleaseStringUTFChars(env, mode, mode_str); 70 | 71 | jlong result = LNG(data); 72 | return result; 73 | } 74 | 75 | JNIEXPORT jlong JNICALL 76 | Java_com_freiheit_gnupg_GnuPGData_gpgmeDataNew(JNIEnv* env, jobject self) 77 | { 78 | gpgme_data_t data; 79 | gpgme_error_t err = gpgme_data_new(&data); 80 | if (UTILS_onErrorThrowException(env, err)) { 81 | return LNG(NULL); 82 | } 83 | 84 | return LNG(data); 85 | } 86 | 87 | JNIEXPORT void JNICALL 88 | Java_com_freiheit_gnupg_GnuPGData_gpgmeDataWrite(JNIEnv* env, jobject self, 89 | jlong data, jobject out) 90 | { 91 | gpgme_error_t err; 92 | 93 | jbyte buf[BUFSIZE]; 94 | size_t nread; 95 | 96 | jclass outputStream = (*env)->GetObjectClass(env, out); 97 | if (outputStream == NULL) { 98 | fprintf(stderr, "output stream NULL! abort.\n"); 99 | return; 100 | } 101 | 102 | jmethodID writeMethod = 103 | (*env)->GetMethodID(env, outputStream, "write", "([BII)V"); 104 | if (writeMethod == NULL) { 105 | fprintf(stderr, "write method NULL! abort.\n"); 106 | return; 107 | } 108 | 109 | jbyteArray jbuf; 110 | 111 | err = (gpgme_data_seek(DATA(data), (off_t)0, SEEK_SET) < 0); 112 | if (UTILS_onErrorThrowException(env, err)) { 113 | fprintf(stderr, "error throw exception! abort.\n"); 114 | return; 115 | } 116 | 117 | int size = 0; 118 | while ((nread = gpgme_data_read(DATA(data), buf, BUFSIZE)) != 0) { 119 | size += nread; 120 | jbuf = (*env)->NewByteArray(env, nread); 121 | if (jbuf == NULL) { 122 | fprintf(stderr, "jbuf is NULL! abort.\n"); 123 | return; 124 | } 125 | (*env)->SetByteArrayRegion(env, jbuf, 0, nread, buf); 126 | (*env)->CallVoidMethod(env, out, writeMethod, jbuf, (jint)0, 127 | (jint)nread); 128 | if ((*env)->ExceptionCheck(env)) { 129 | (*env)->DeleteLocalRef(env, jbuf); 130 | return; 131 | } 132 | (*env)->DeleteLocalRef(env, jbuf); 133 | } 134 | 135 | } 136 | 137 | JNIEXPORT void JNICALL 138 | Java_com_freiheit_gnupg_GnuPGData_gpgmeDataRelease(JNIEnv* env, jobject self, 139 | jlong data) 140 | { 141 | gpgme_data_t dh = DATA(data); 142 | if (dh->data.stream != NULL) 143 | fclose(dh->data.stream); 144 | gpgme_data_release(dh); 145 | } 146 | 147 | JNIEXPORT void JNICALL 148 | Java_com_freiheit_gnupg_GnuPGData_gpgmeDataRead(JNIEnv* env, jobject self, 149 | jlong data, jobject in) 150 | { 151 | gpgme_error_t err; 152 | 153 | jclass inputStream = (*env)->GetObjectClass(env, in); 154 | if (inputStream == NULL) { 155 | fprintf(stderr, "input stream NULL! abort.\n"); 156 | return; 157 | } 158 | 159 | jmethodID readMethod = (*env)->GetMethodID(env, inputStream, 160 | "read", "([BII)I"); 161 | if (readMethod == NULL) { 162 | fprintf(stderr, "read method NULL! abort.\n"); 163 | return; 164 | } 165 | 166 | jbyteArray jbuf = (*env)->NewByteArray(env, BUFSIZE); //GETMEM(0) 167 | jlong nread; 168 | 169 | err = (gpgme_data_seek(DATA(data), (off_t)0, SEEK_SET) < 0); 170 | if (UTILS_onErrorThrowException(env, err)) { 171 | return; 172 | } 173 | 174 | while ((nread = (*env)->CallIntMethod(env, in, readMethod, 175 | jbuf, (jint)0, BUFSIZE)) != -1) { 176 | 177 | jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL); 178 | if (buf == NULL) { 179 | return; 180 | } 181 | 182 | gpgme_data_write(DATA(data), buf, nread); 183 | if ((*env)->ExceptionCheck(env)) { 184 | (*env)->DeleteLocalRef(env, jbuf); 185 | return; 186 | } 187 | 188 | } 189 | (*env)->DeleteLocalRef(env, jbuf); //RELMEM(0) 190 | 191 | } 192 | 193 | /* 194 | * Local Variables: 195 | * tab-width: 4; 196 | * c-basic-offset: 4; 197 | * c-file-style: k&r; 198 | * indent-tabs-mode: nil; 199 | * End: 200 | */ 201 | -------------------------------------------------------------------------------- /jni/GnuPGGenkeyResult.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "gpgmeutils.h" 6 | #include "com_freiheit_gnupg_GnuPGGenkeyResult.h" 7 | 8 | 9 | JNIEXPORT jstring JNICALL 10 | Java_com_freiheit_gnupg_GnuPGGenkeyResult_gpgmeGetFpr(JNIEnv* env, 11 | jobject self, 12 | jlong result) 13 | { 14 | jstring str = (*env)->NewStringUTF(env, (GENKEYRESULT(result))->fpr); 15 | return str; 16 | } 17 | 18 | JNIEXPORT jboolean JNICALL 19 | Java_com_freiheit_gnupg_GnuPGGenkeyResult_gpgmeGetPrimary(JNIEnv* env, 20 | jobject self, 21 | jlong result) 22 | { 23 | return (GENKEYRESULT(result))->primary; 24 | } 25 | 26 | JNIEXPORT jboolean JNICALL 27 | Java_com_freiheit_gnupg_GnuPGGenkeyResult_gpgmeGetSub(JNIEnv* env, 28 | jobject self, 29 | jlong result) 30 | { 31 | return (GENKEYRESULT(result))->primary; 32 | } 33 | 34 | /* 35 | * Local Variables: 36 | * tab-width: 4; 37 | * c-basic-offset: 4; 38 | * c-file-style: k&r; 39 | * indent-tabs-mode: nil; 40 | * End: 41 | */ 42 | -------------------------------------------------------------------------------- /jni/GnuPGKey.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "gpgmeutils.h" 6 | #include "com_freiheit_gnupg_GnuPGKey.h" 7 | 8 | 9 | JNIEXPORT jlong JNICALL 10 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeGetKey(JNIEnv* env, jobject self, 11 | jlong context, jstring fingerprint, 12 | jboolean secret) 13 | { 14 | gpgme_key_t key; 15 | 16 | const char* fpr = (*env)->GetStringUTFChars(env, fingerprint, NULL); 17 | gpgme_error_t err = gpgme_get_key(CONTEXT(context), fpr, &key, secret); 18 | if (UTILS_onErrorThrowException(env, err)) { 19 | (*env)->ReleaseStringUTFChars(env, fingerprint, fpr); 20 | return LNG(NULL); 21 | } 22 | (*env)->ReleaseStringUTFChars(env, fingerprint, fpr); 23 | 24 | //setMembers(env, self, key); 25 | 26 | return LNG(key); 27 | } 28 | 29 | JNIEXPORT jlong JNICALL 30 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeKeyUnref(JNIEnv* env, jobject self, 31 | jlong key) 32 | { 33 | gpgme_key_unref(KEY(key)); 34 | return 0l; 35 | } 36 | 37 | JNIEXPORT jstring JNICALL 38 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeGetName(JNIEnv* env, jobject self, 39 | jlong key) 40 | { 41 | jstring str = (*env)->NewStringUTF(env, (KEY(key))->uids->name); 42 | return str; 43 | } 44 | 45 | JNIEXPORT jstring JNICALL 46 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeGetEmail(JNIEnv* env, jobject self, 47 | jlong key) 48 | { 49 | jstring str = (*env)->NewStringUTF(env, (KEY(key))->uids->email); 50 | return str; 51 | } 52 | 53 | JNIEXPORT jstring JNICALL 54 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeGetKeyID(JNIEnv* env, jobject self, 55 | jlong key) 56 | { 57 | jstring str = (*env)->NewStringUTF(env, (KEY(key))->subkeys->keyid); 58 | return str; 59 | } 60 | 61 | JNIEXPORT jlong JNICALL 62 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeGetTimestamp(JNIEnv* env, jobject self, 63 | jlong key) 64 | { 65 | return (KEY(key))->subkeys->timestamp; 66 | } 67 | 68 | JNIEXPORT jstring JNICALL 69 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeGetFingerprint(JNIEnv* env, jobject self, 70 | jlong key) 71 | { 72 | jstring str = (*env)->NewStringUTF(env, (KEY(key))->subkeys->fpr); 73 | return str; 74 | } 75 | 76 | JNIEXPORT jstring JNICALL 77 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeGetComment(JNIEnv* env, jobject self, 78 | jlong key) 79 | { 80 | jstring str = (*env)->NewStringUTF(env, (KEY(key))->uids->comment); 81 | return str; 82 | } 83 | 84 | JNIEXPORT jstring JNICALL 85 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeGetUserID(JNIEnv* env, jobject self, 86 | jlong key) 87 | { 88 | jstring str = (*env)->NewStringUTF(env, (KEY(key))->uids->uid); 89 | return str; 90 | } 91 | 92 | JNIEXPORT jlong JNICALL 93 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeGetSignature(JNIEnv* env, jobject self, 94 | jlong key) 95 | { 96 | return LNG((KEY(key))->uids->signatures); 97 | } 98 | 99 | JNIEXPORT jboolean JNICALL 100 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeCanEncrypt(JNIEnv* env, jobject self, 101 | jlong key) 102 | { 103 | return (KEY(key))->can_encrypt; 104 | } 105 | 106 | JNIEXPORT jboolean JNICALL 107 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeCanSign(JNIEnv* env, jobject self, 108 | jlong key) 109 | { 110 | return (KEY(key))->can_sign; 111 | } 112 | 113 | JNIEXPORT jboolean JNICALL 114 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeCanCerify(JNIEnv* env, jobject self, 115 | jlong key) 116 | { 117 | return (KEY(key))->can_certify; 118 | } 119 | 120 | JNIEXPORT jboolean JNICALL 121 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeCanAuthenticate(JNIEnv* env, jobject self, 122 | jlong key) 123 | { 124 | return (KEY(key))->can_authenticate; 125 | } 126 | 127 | JNIEXPORT jboolean JNICALL 128 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeIsRevoked(JNIEnv* env, jobject self, 129 | jlong key) 130 | { 131 | return (KEY(key))->revoked; 132 | } 133 | 134 | JNIEXPORT jboolean JNICALL 135 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeIsExpired(JNIEnv* env, jobject self, 136 | jlong key) 137 | { 138 | return (KEY(key))->expired; 139 | } 140 | 141 | JNIEXPORT jboolean JNICALL 142 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeIsDisabled(JNIEnv* env, jobject self, 143 | jlong key) 144 | { 145 | return (KEY(key))->disabled; 146 | } 147 | 148 | JNIEXPORT jboolean JNICALL 149 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeIsInvalid(JNIEnv* env, jobject self, 150 | jlong key) 151 | { 152 | return (KEY(key))->invalid; 153 | } 154 | 155 | JNIEXPORT jboolean JNICALL 156 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeIsQualified(JNIEnv* env, jobject self, 157 | jlong key) 158 | { 159 | return (KEY(key))->is_qualified; 160 | } 161 | 162 | JNIEXPORT jboolean JNICALL 163 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeIsSecret(JNIEnv* env, jobject self, 164 | jlong key) 165 | { 166 | return (KEY(key))->secret; 167 | } 168 | 169 | JNIEXPORT jboolean JNICALL 170 | Java_com_freiheit_gnupg_GnuPGKey_gpgmeHasSecretKey(JNIEnv* env, jobject self, 171 | jlong key) 172 | { 173 | gpgme_subkey_t subkey; 174 | for (subkey = KEY(key)->subkeys; subkey; subkey = subkey->next) 175 | if (subkey->secret) 176 | return 1; 177 | return 0; 178 | } 179 | 180 | /* void */ 181 | /* setMembers(JNIEnv *env, jobject self, gpgme_key_t key){ */ 182 | /* jclass cls = (*env)->GetObjectClass(env, self); */ 183 | 184 | /* jfieldID uid_fld = (*env)->GetFieldID(env, cls, "_uid", "Ljava/lang/String;"); */ 185 | /* if(uid_fld == NULL) return; */ 186 | /* jfieldID name_fld = (*env)->GetFieldID(env, cls, "_name", "Ljava/lang/String;"); */ 187 | /* if(name_fld == NULL) return; */ 188 | /* jfieldID email_fld = (*env)->GetFieldID(env, cls, "_email", "Ljava/lang/String;"); */ 189 | /* if(email_fld == NULL) return; */ 190 | /* jfieldID keyid_fld = (*env)->GetFieldID(env, cls, "_keyid", "Ljava/lang/String;"); */ 191 | /* if(keyid_fld == NULL) return; */ 192 | /* jfieldID fpr_fld = (*env)->GetFieldID(env, cls, "_fpr", "Ljava/lang/String;"); */ 193 | /* if(fpr_fld == NULL) return; */ 194 | 195 | /* jstring uid_jstr = (*env)->NewStringUTF(env, key->uids->uid); */ 196 | /* if(uid_jstr == NULL) return; */ 197 | /* (*env)->SetObjectField(env, self, uid_fld, uid_jstr); */ 198 | 199 | /* jstring name_jstr = (*env)->NewStringUTF(env, key->uids->name); */ 200 | /* if(name_jstr == NULL) return; */ 201 | /* (*env)->SetObjectField(env, self, name_fld, name_jstr); */ 202 | 203 | /* jstring email_jstr = (*env)->NewStringUTF(env, key->uids->email); */ 204 | /* if(email_jstr == NULL) return; */ 205 | /* (*env)->SetObjectField(env, self, email_fld, email_jstr); */ 206 | 207 | /* jstring keyid_jstr = (*env)->NewStringUTF(env, key->subkeys->keyid); */ 208 | /* if(keyid_jstr == NULL) return; */ 209 | /* (*env)->SetObjectField(env, self, keyid_fld, keyid_jstr); */ 210 | 211 | /* jstring fpr_jstr = (*env)->NewStringUTF(env, key->subkeys->fpr); */ 212 | /* if(fpr_jstr == NULL) return; */ 213 | /* (*env)->SetObjectField(env, self, fpr_fld, fpr_jstr); */ 214 | 215 | /* } */ 216 | 217 | /* 218 | * Local Variables: 219 | * tab-width: 4; 220 | * c-basic-offset: 4; 221 | * c-file-style: k&r; 222 | * indent-tabs-mode: nil; 223 | * End: 224 | */ 225 | -------------------------------------------------------------------------------- /jni/GnuPGSignature.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "gpgmeutils.h" 6 | #include "com_freiheit_gnupg_GnuPGSignature.h" 7 | 8 | 9 | JNIEXPORT jboolean JNICALL 10 | Java_com_freiheit_gnupg_GnuPGSignature_gpgmeGetRevoked(JNIEnv* env, 11 | jobject self, jlong sig) 12 | { 13 | return (jboolean)(KEYSIG(sig))->revoked; 14 | } 15 | 16 | JNIEXPORT jboolean JNICALL 17 | Java_com_freiheit_gnupg_GnuPGSignature_gpgmeGetExpired(JNIEnv* env, 18 | jobject self, jlong sig) 19 | { 20 | return (jboolean)(KEYSIG(sig))->expired; 21 | } 22 | 23 | JNIEXPORT jboolean JNICALL 24 | Java_com_freiheit_gnupg_GnuPGSignature_gpgmeGetInvalid(JNIEnv* env, 25 | jobject self, jlong sig) 26 | { 27 | return (jboolean)(KEYSIG(sig))->invalid; 28 | } 29 | 30 | JNIEXPORT jboolean JNICALL 31 | Java_com_freiheit_gnupg_GnuPGSignature_gpgmeGetExportable(JNIEnv* env, 32 | jobject self, 33 | jlong sig) 34 | { 35 | return (jboolean)(KEYSIG(sig))->exportable; 36 | } 37 | 38 | JNIEXPORT jstring JNICALL 39 | Java_com_freiheit_gnupg_GnuPGSignature_gpgmeGetKeyID(JNIEnv* env, jobject self, 40 | jlong sig) 41 | { 42 | jstring str = (*env)->NewStringUTF(env, (KEYSIG(sig))->keyid); 43 | return str; 44 | } 45 | 46 | JNIEXPORT jstring JNICALL 47 | Java_com_freiheit_gnupg_GnuPGSignature_gpgmeGetUserID(JNIEnv* env, 48 | jobject self, jlong sig) 49 | { 50 | jstring str = (*env)->NewStringUTF(env, (KEYSIG(sig))->uid); 51 | return str; 52 | } 53 | 54 | JNIEXPORT jstring JNICALL 55 | Java_com_freiheit_gnupg_GnuPGSignature_gpgmeGetName(JNIEnv* env, jobject self, 56 | jlong sig) 57 | { 58 | jstring str = (*env)->NewStringUTF(env, (KEYSIG(sig))->name); 59 | return str; 60 | } 61 | 62 | JNIEXPORT jstring JNICALL 63 | Java_com_freiheit_gnupg_GnuPGSignature_gpgmeGetEmail(JNIEnv* env, jobject self, 64 | jlong sig) 65 | { 66 | jstring str = (*env)->NewStringUTF(env, (KEYSIG(sig))->email); 67 | return str; 68 | } 69 | 70 | JNIEXPORT jstring JNICALL 71 | Java_com_freiheit_gnupg_GnuPGSignature_gpgmeGetComment(JNIEnv* env, 72 | jobject self, jlong sig) 73 | { 74 | jstring str = (*env)->NewStringUTF(env, (KEYSIG(sig))->comment); 75 | return str; 76 | } 77 | 78 | JNIEXPORT jlong JNICALL 79 | Java_com_freiheit_gnupg_GnuPGSignature_gpgmeGetNextSignature(JNIEnv* env, 80 | jobject self, 81 | jlong sig) 82 | { 83 | return LNG((KEYSIG(sig))->next); 84 | } 85 | 86 | /* 87 | * Local Variables: 88 | * tab-width: 4; 89 | * c-basic-offset: 4; 90 | * c-file-style: k&r; 91 | * indent-tabs-mode: nil; 92 | * End: 93 | */ 94 | -------------------------------------------------------------------------------- /jni/data.h: -------------------------------------------------------------------------------- 1 | /* data.h - Internal data object abstraction interface. 2 | Copyright (C) 2002, 2004, 2005 g10 Code GmbH 3 | 4 | This file is part of GPGME. 5 | 6 | GPGME is free software; you can redistribute it and/or modify it 7 | under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation; either version 2.1 of 9 | the License, or (at your option) any later version. 10 | 11 | GPGME is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with this program; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 19 | 02111-1307, USA. */ 20 | 21 | #ifndef DATA_H 22 | #define DATA_H 23 | 24 | #if HAVE_CONFIG_H 25 | #include 26 | #endif 27 | 28 | #ifdef HAVE_SYS_TYPES_H 29 | # include 30 | #endif 31 | #include 32 | 33 | #include "gpgme.h" 34 | 35 | 36 | /* Read up to SIZE bytes into buffer BUFFER from the data object with 37 | the handle DH. Return the number of characters read, 0 on EOF and 38 | -1 on error. If an error occurs, errno is set. */ 39 | typedef gpgme_ssize_t (*gpgme_data_read_cb)(gpgme_data_t dh, 40 | void* buffer, 41 | size_t size); 42 | 43 | /* Write up to SIZE bytes from buffer BUFFER to the data object with 44 | the handle DH. Return the number of characters written, or -1 on 45 | error. If an error occurs, errno is set. */ 46 | typedef gpgme_ssize_t (*gpgme_data_write_cb)(gpgme_data_t dh, 47 | const void* buffer, 48 | size_t size); 49 | 50 | /* Set the current position from where the next read or write starts 51 | in the data object with the handle DH to OFFSET, relativ to 52 | WHENCE. */ 53 | typedef gpgme_off_t (*gpgme_data_seek_cb)(gpgme_data_t dh, 54 | gpgme_off_t offset, 55 | int whence); 56 | 57 | /* Release the data object with the handle DH. */ 58 | typedef void (*gpgme_data_release_cb)(gpgme_data_t dh); 59 | 60 | /* Get the FD associated with the handle DH, or -1. */ 61 | typedef int (*gpgme_data_get_fd_cb)(gpgme_data_t dh); 62 | 63 | struct _gpgme_data_cbs { 64 | gpgme_data_read_cb read; 65 | gpgme_data_write_cb write; 66 | gpgme_data_seek_cb seek; 67 | gpgme_data_release_cb release; 68 | gpgme_data_get_fd_cb get_fd; 69 | }; 70 | 71 | struct gpgme_data { 72 | struct _gpgme_data_cbs* cbs; 73 | gpgme_data_encoding_t encoding; 74 | 75 | #ifdef PIPE_BUF 76 | #define BUFFER_SIZE PIPE_BUF 77 | #else 78 | #ifdef _POSIX_PIPE_BUF 79 | #define BUFFER_SIZE _POSIX_PIPE_BUF 80 | #else 81 | #define BUFFER_SIZE 512 82 | #endif 83 | #endif 84 | char pending[BUFFER_SIZE]; 85 | int pending_len; 86 | 87 | /* File name of the data object. */ 88 | char* file_name; 89 | 90 | union { 91 | /* For gpgme_data_new_from_fd. */ 92 | int fd; 93 | 94 | /* For gpgme_data_new_from_stream. */ 95 | FILE* stream; 96 | 97 | /* For gpgme_data_new_from_cbs. */ 98 | struct { 99 | gpgme_data_cbs_t cbs; 100 | void* handle; 101 | } user; 102 | 103 | /* For gpgme_data_new_from_mem. */ 104 | struct { 105 | char* buffer; 106 | const char* orig_buffer; 107 | /* Allocated size of BUFFER. */ 108 | size_t size; 109 | size_t length; 110 | gpgme_off_t offset; 111 | } mem; 112 | 113 | /* For gpgme_data_new_from_read_cb. */ 114 | struct { 115 | int (*cb)(void*, char*, size_t, size_t*); 116 | void* handle; 117 | } old_user; 118 | } data; 119 | }; 120 | 121 | 122 | gpgme_error_t _gpgme_data_new(gpgme_data_t* r_dh, 123 | struct _gpgme_data_cbs* cbs); 124 | 125 | void _gpgme_data_release(gpgme_data_t dh); 126 | 127 | /* Get the file descriptor associated with DH, if possible. Otherwise 128 | return -1. */ 129 | int _gpgme_data_get_fd(gpgme_data_t dh); 130 | 131 | #endif /* DATA_H */ 132 | 133 | /* 134 | * Local Variables: 135 | * tab-width: 4; 136 | * c-basic-offset: 4; 137 | * c-file-style: k&r; 138 | * indent-tabs-mode: nil; 139 | * End: 140 | */ 141 | -------------------------------------------------------------------------------- /jni/format-code.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | ASTYLE=`which astyle 2> /dev/null` 4 | if [[ $? -ne 0 ]]; then 5 | echo "astyle code formatter not installed. aborting." 6 | exit 1 7 | fi 8 | 9 | ASTYLE_ARGS="--style=kr --indent=spaces=4 --convert-tabs --pad-oper --unpad-paren --pad-header --align-pointer=type --align-reference=type" 10 | 11 | $ASTYLE $ASTYLE_ARGS *.h 12 | $ASTYLE $ASTYLE_ARGS *.c 13 | 14 | -------------------------------------------------------------------------------- /jni/gpgmeutils.c: -------------------------------------------------------------------------------- 1 | #include "gpgmeutils.h" 2 | #include 3 | 4 | #define BUF_LEN 1024 5 | 6 | jboolean 7 | UTILS_setStringMember(JNIEnv* env, jobject self, jclass selfclass, 8 | const char* fieldname, const char* fieldvalue) 9 | { 10 | //get the field from the class 11 | jfieldID fld = 12 | (*env)->GetFieldID(env, selfclass, fieldname, "Ljava/lang/String;"); 13 | if (fld == NULL) { 14 | return JNI_FALSE; 15 | } 16 | 17 | jstring jval = (*env)->NewStringUTF(env, fieldvalue); 18 | if (jval == NULL) { 19 | return JNI_FALSE; 20 | } 21 | (*env)->SetObjectField(env, self, fld, jval); 22 | return JNI_TRUE; 23 | } 24 | 25 | jboolean 26 | UTILS_setIntMember(JNIEnv* env, jobject self, jclass selfclass, 27 | const char* fieldname, int fieldvalue) 28 | { 29 | //get the field from the class 30 | 31 | jlong jval = (jlong) fieldvalue; 32 | 33 | jfieldID fld = (*env)->GetFieldID(env, selfclass, fieldname, "I"); 34 | if (fld == NULL) { 35 | return JNI_FALSE; 36 | } 37 | 38 | if (jval == 0) { 39 | return JNI_FALSE; 40 | } 41 | (*env)->SetIntField(env, self, fld, jval); 42 | return JNI_TRUE; 43 | } 44 | 45 | void 46 | UTILS_setBooleanMember(JNIEnv* env, jobject self, jclass selfclass, 47 | const char* fieldname, unsigned int fieldvalue) 48 | { 49 | //get the field from the class 50 | 51 | jboolean jval = (jboolean) fieldvalue; 52 | 53 | jfieldID fld = (*env)->GetFieldID(env, selfclass, fieldname, "Z"); 54 | if (fld == NULL) { 55 | return; 56 | } 57 | 58 | if (jval == 0) { 59 | return; 60 | } 61 | (*env)->SetBooleanField(env, self, fld, jval); 62 | } 63 | 64 | jboolean UTILS_onErrorThrowException(JNIEnv* env, gpgme_error_t err) 65 | { 66 | if (err) { 67 | char exceptionString[BUF_LEN]; /* this is enough */ 68 | int spaceUsed; 69 | jclass exception = 70 | (*env)->FindClass(env, "com/freiheit/gnupg/GnuPGException"); 71 | 72 | if (exception == NULL) { 73 | return JNI_TRUE; 74 | } 75 | spaceUsed = snprintf(exceptionString, BUF_LEN, "%u: ", err); 76 | gpgme_strerror_r(err, exceptionString + spaceUsed, BUF_LEN - spaceUsed); 77 | (*env)->ThrowNew(env, exception, exceptionString); 78 | (*env)->DeleteLocalRef(env, exception); 79 | return JNI_TRUE; 80 | } else { 81 | return JNI_FALSE; 82 | } 83 | } 84 | 85 | int 86 | UTILS_copyRecipientsFromJvm(JNIEnv* env, jlongArray recipients, 87 | gpgme_key_t keys[]) 88 | { 89 | //how many keys from recipients did we receive? 90 | jsize len = (*env)->GetArrayLength(env, recipients); 91 | if (len < 1) { 92 | return len; 93 | } 94 | 95 | //allocate native memory from recipient keys 96 | jlong* carr = (*env)->GetLongArrayElements(env, recipients, NULL); 97 | if (carr == NULL) { 98 | return -1; 99 | } 100 | //copy recipient keys to new array... 101 | int i; 102 | for (i = 0; i < len; i++) { 103 | keys[i] = KEY(carr[i]); 104 | } 105 | //and mark the end of the array with a NULL. 106 | keys[len] = NULL; 107 | 108 | //release the memory allocated from the recipients key list 109 | (*env)->ReleaseLongArrayElements(env, recipients, carr, 0); 110 | 111 | return len; 112 | } 113 | 114 | /* 115 | * Local Variables: 116 | * tab-width: 4; 117 | * c-basic-offset: 4; 118 | * c-file-style: k&r; 119 | * indent-tabs-mode: nil; 120 | * End: 121 | */ 122 | -------------------------------------------------------------------------------- /jni/gpgmeutils.h: -------------------------------------------------------------------------------- 1 | #ifndef GPGME_JAVA_UTILS 2 | #define GPGME_JAVA_UTILS 3 | 4 | #include 5 | #include 6 | 7 | jboolean UTILS_setStringMember(JNIEnv* env, jobject self, jclass selfclass, 8 | const char* fieldname, const char* fieldvalue); 9 | 10 | jboolean UTILS_setIntMember(JNIEnv* env, jobject self, jclass selfclass, 11 | const char* fieldname, int fieldvalue); 12 | 13 | void UTILS_setBooleanMember(JNIEnv* env, jobject self, jclass selfclass, 14 | const char* fieldname, unsigned int fieldvalue); 15 | 16 | jboolean UTILS_onErrorThrowException(JNIEnv* env, gpgme_error_t err); 17 | 18 | int UTILS_copyRecipientsFromJvm(JNIEnv* env, jlongArray recipients, gpgme_key_t keys[]); 19 | 20 | /* use this macro to convert a jlong variable to a pointer to a gpgme context in a safe and portable way */ 21 | #define CONTEXT(c) ((gpgme_ctx_t)_ptrFromJLong(c)) 22 | /* use this macro to convert a jlong variable to a pointer to a gpgme data buffer in a safe and portable way */ 23 | #define DATA(c) ((gpgme_data_t)_ptrFromJLong(c)) 24 | /* use this macro to convert a jlong variable to a pointer to a gpgme genkey result in a safe and portable way */ 25 | #define GENKEYRESULT(c) ((gpgme_genkey_result_t)_ptrFromJLong(c)) 26 | /* use this macro to convert a jlong variable to a pointer to a gpgme key signature in a safe and portable way */ 27 | #define KEYSIG(c) ((gpgme_key_sig_t)_ptrFromJLong(c)) 28 | /* use this macro to convert a jlong variable to a pointer to a gpgme key in a safe and portable way */ 29 | #define KEY(c) ((gpgme_key_t)_ptrFromJLong(c)) 30 | 31 | /* use this macro to convert a pointer variable back to a jlong in a safe and portable way */ 32 | #define LNG(a) (_jlongFromPtr(a)) 33 | 34 | // don't use this directly, it is wrapped by the PTR() macro 35 | inline static void* _ptrFromJLong(jlong l) 36 | { 37 | return (void*)(unsigned long) l; 38 | } 39 | 40 | // don't use this directly, it is wrapped by the PTR() macro 41 | inline static jlong _jlongFromPtr(void* p) 42 | { 43 | return (jlong)(unsigned long) p; 44 | } 45 | #endif 46 | 47 | /* 48 | * Local Variables: 49 | * tab-width: 4; 50 | * c-basic-offset: 4; 51 | * c-file-style: k&r; 52 | * indent-tabs-mode: nil; 53 | * End: 54 | */ 55 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.gnupg 4 | gnupg-for-java 5 | 0.2-pre-SNAPSHOT 6 | 7 | src 8 | 9 | 10 | maven-compiler-plugin 11 | 3.1 12 | 13 | 1.7 14 | 1.7 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-antrun-plugin 20 | 1.7 21 | 22 | 23 | process-classes 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | run 40 | 41 | 42 | 43 | 44 | 45 | com.sun 46 | tools 47 | 1.7.0 48 | system 49 | ${java.home}/../lib/tools.jar 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | junit 58 | junit 59 | 4.7 60 | compile 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/com/freiheit/gnupg/GnuPGContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: GnuPGContext.java,v 1.4 2006/07/03 15:32:16 sneumann Exp $ 3 | * (c) Copyright 2005 freiheit.com technologies gmbh, Germany. 4 | * 5 | * This file is part of Java for GnuPG (http://www.freiheit.com). 6 | * 7 | * Java for GnuPG is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation; either version 2.1 10 | * of the License, or (at your option) any later version. 11 | * 12 | * Please see COPYING for the complete licence. 13 | */ 14 | 15 | package com.freiheit.gnupg; 16 | 17 | import java.io.BufferedOutputStream; 18 | import java.io.ByteArrayOutputStream; 19 | import java.io.File; 20 | import java.io.IOException; 21 | 22 | /** 23 | * Start here, because for all operations, you first need to create a 24 | * GnuPGContext. Use one context object for every single thread or (really) take 25 | * care about synchronizing access to the context from different threads. 26 | *

27 | * How to create a context? 28 | * 29 | *

 30 |  * {
 31 |  *     @code
 32 |  *     GnuPGContext ctx = new GnuPGContext();
 33 |  * }
 34 |  * 
35 | * 36 | * @author Stefan Richter, stefan@freiheit.com 37 | */ 38 | 39 | public class GnuPGContext extends GnuPGPeer { 40 | public static final String TAG = "GnuPGContext"; 41 | static { 42 | System.loadLibrary("gnupg-for-java"); 43 | } 44 | 45 | private String _version; 46 | private String _filename; 47 | private String _reqversion; 48 | private int _protocol; 49 | 50 | /** Creates a new Context (use on context for one thread!) */ 51 | public GnuPGContext() { 52 | gpgmeGetEngineInfo(); 53 | setInternalRepresentation(gpgmeNew()); 54 | } 55 | 56 | /** 57 | * Returns the version of the underlying GPGME lib version. 58 | * 59 | * @return library version as String (like "1.1.1") 60 | */ 61 | public String getVersion() { 62 | return _version; 63 | } 64 | 65 | /** 66 | * Returns the executable gpg with path 67 | * 68 | * @return gpg executable as String (like "/usr/bin/gpg") 69 | */ 70 | public String getFilename() { 71 | return _filename; 72 | } 73 | 74 | /** 75 | * Returns the required version of the underlying GPGME lib. 76 | * 77 | * @return required library version as String (like "1.1.1") 78 | */ 79 | public String getRequiredVersion() { 80 | return _reqversion; 81 | } 82 | 83 | /** 84 | * Returns the used protocol of the crypto backend. 85 | * 86 | * @return protocol 87 | */ 88 | public int getProtocol() { 89 | return _protocol; 90 | } 91 | 92 | /** 93 | * Tells you, is the gpg engine uses ASCII armor. Please check GPG/GPGME for 94 | * documentation if you don't know what this means. (Try 'man gpg' on the 95 | * command line and look for 'armor') 96 | * 97 | * @return boolean true if results will be ASCII armored, if false binary 98 | */ 99 | public boolean isArmor() { 100 | return gpgmeGetArmor(getInternalRepresentation()); 101 | } 102 | 103 | /** 104 | * Tell the gpg engine to use ASCII armor. Please check GPG/GPGME for 105 | * documentation if you don't know what this means. (Try 'man gpg' on the 106 | * command line and look for 'armor') 107 | * 108 | * @param state set true if results should be ASCII armored, set false if 109 | * binary 110 | */ 111 | public void setArmor(boolean state) { 112 | gpgmeSetArmor(getInternalRepresentation(), state); 113 | } 114 | 115 | /** 116 | * Tells you, is the gpg engine is in text mode. Please check GPG/GPGME for 117 | * documentation if you don't know what this means. 118 | * 119 | * @return boolean true means text mode is on 120 | */ 121 | public boolean isTextmode() { 122 | return gpgmeGetTextmode(getInternalRepresentation()); 123 | } 124 | 125 | /** 126 | * Get the current text mode from the gpg engine. Please check GPG/GPGME for 127 | * documentation if you don't know what this means. 128 | * 129 | * @return boolean if textmode is currently enabled 130 | */ 131 | public boolean getTextmode() { 132 | return gpgmeGetTextmode(getInternalRepresentation()); 133 | } 134 | 135 | /** 136 | * Tell the gpg engine to set the text mode. Please check GPG/GPGME for 137 | * documentation if you don't know what this means. 138 | * 139 | * @param state set true if you want text mode switched on 140 | */ 141 | public void setTextmode(boolean state) { 142 | gpgmeSetTextmode(getInternalRepresentation(), state); 143 | } 144 | 145 | private long[] getInternalRepresentationFromRecipients(GnuPGKey[] recipients) { 146 | // note that these are pointers to addresses in the gnupg-for-java 147 | // shared lib 148 | long recipientsInternals[] = new long[recipients.length]; 149 | for (int i = 0; i < recipients.length; i++) { 150 | if (recipients[i] != null) 151 | recipientsInternals[i] = recipients[i].getInternalRepresentation(); 152 | else 153 | ; // FIXME: throw exception here? Just skip over it for now. 154 | } 155 | return recipientsInternals; 156 | } 157 | 158 | private boolean hasNoRecipients(GnuPGKey[] recipients) { 159 | return !(recipients != null && recipients.length > 0); 160 | } 161 | 162 | /** 163 | * Gets the public key with the supplied fingerprint from the keyring. This 164 | * is also kind of a factory method to generate key objects, because you 165 | * always need a context to access the keys in your keyring. 166 | * 167 | * @param fingerprint 16 char hex fingerprint of key in your keyring 168 | * @return GnuPGKey the public key that matches the fingerprint 169 | * @see com.freiheit.gnupg.GnuPGKey 170 | */ 171 | public GnuPGKey getKeyByFingerprint(String fingerprint) throws GnuPGException { 172 | if (fingerprint == null || fingerprint.length() < 1) { 173 | return null; 174 | } else { 175 | return new GnuPGKey(this, fingerprint, false); 176 | } 177 | } 178 | 179 | /** 180 | * Gets the secret key with the supplied fingerprint from the keyring. This 181 | * is also kind of a factory method to generate secret key objects, because 182 | * you always need a context to access the keys in your keyring. 183 | * 184 | * @param fingerprint 16 char hex fingerprint of key in your keyring 185 | * @return GnuPGKey the secret key that matches the fingerprint 186 | * @see com.freiheit.gnupg.GnuPGKey 187 | */ 188 | public GnuPGKey getSecretKeyByFingerprint(String fingerprint) 189 | throws GnuPGException { 190 | if (fingerprint == null || fingerprint.length() < 1) { 191 | return null; 192 | } else { 193 | return new GnuPGKey(this, fingerprint, true); 194 | } 195 | } 196 | 197 | /** 198 | * Factory method to generate a GnuPGData instance from a File. 199 | * 200 | * @param f should not be null or a directory and must be readable 201 | * @return GnuPGData instance with data from f, unless 202 | * f is has no readable data in it, then it returns 203 | * null 204 | * @throws IOException 205 | * @see com.freiheit.gnupg.GnuPGData 206 | */ 207 | public GnuPGData createDataObject(File f) throws GnuPGException, IOException { 208 | if (f != null && f.exists() && !f.isDirectory() && f.canRead()) { 209 | return new GnuPGData(f); 210 | } 211 | return null; 212 | } 213 | 214 | /** 215 | * Factory method to generate a GnuPGData instance from a String. 216 | * 217 | * @param data should not be null and should have a length > 0 218 | * @return GnuPGData instance based on data, unless 219 | * data is null or has a length of 0, then it returns 220 | * null 221 | * @see com.freiheit.gnupg.GnuPGData 222 | */ 223 | public GnuPGData createDataObject(String data) throws GnuPGException { 224 | if (data == null || data.length() < 1) { 225 | return null; 226 | } 227 | else { 228 | return new GnuPGData(data); 229 | } 230 | } 231 | 232 | /** 233 | * Factory method to generate a GnuPGData instance from a byte array. 234 | * 235 | * @param data should not be null and should have a length > 0 236 | * @return GnuPGData instance based on data, unless 237 | * data is null or has a length of 0, then it returns 238 | * null 239 | * @see com.freiheit.gnupg.GnuPGData 240 | */ 241 | public GnuPGData createDataObject(byte[] data) throws GnuPGException { 242 | if (data == null || data.length < 1) { 243 | return null; 244 | } 245 | else { 246 | return new GnuPGData(data); 247 | } 248 | } 249 | 250 | /** 251 | * Factory method to generate an empty GnuPGData instance. 252 | * 253 | * @return an empty GnuPGData instance 254 | * @see com.freiheit.gnupg.GnuPGData 255 | */ 256 | public GnuPGData createDataObject() throws GnuPGException { 257 | return new GnuPGData(); 258 | } 259 | 260 | /** 261 | * Convenience method to generate empty key arrays. To encrypt data, you 262 | * need to supply a list of recipients in an array. This is a little helper. 263 | * It will not search for keys! Its just an empty array. 264 | * 265 | * @param withLengthOf length of the array to generate (number of 266 | * recipients) 267 | * @return GnuPGKey empty array of keys 268 | * @see com.freiheit.gnupg.GnuPGKey 269 | */ 270 | public GnuPGKey[] generateEmptyKeyArray(int withLengthOf) { 271 | if (withLengthOf < 1) { 272 | return null; 273 | } 274 | else { 275 | return new GnuPGKey[withLengthOf]; 276 | } 277 | } 278 | 279 | /** 280 | * List all public keys in keyring. 281 | * 282 | * @return GnuPGKey array of key objects with all public keys 283 | * @see com.freiheit.gnupg.GnuPGKey 284 | */ 285 | public GnuPGKey[] listKeys() throws GnuPGException { 286 | return searchKeys(""); 287 | } 288 | 289 | /** 290 | * List all secret keys in keyring. 291 | * 292 | * @return GnuPGKey array of key objects with all secret keys 293 | * @see com.freiheit.gnupg.GnuPGKey 294 | */ 295 | public GnuPGKey[] listSecretKeys() throws GnuPGException { 296 | return searchSecretKeys(""); 297 | } 298 | 299 | /** 300 | * Find all public keys matching query in keyring. 301 | * 302 | * @param query allows the same expressions as gpg on command line 303 | * @return GnuPGKey array of key objects with all matching keys 304 | * @see com.freiheit.gnupg.GnuPGKey 305 | */ 306 | public GnuPGKey[] searchKeys(String query) throws GnuPGException { 307 | if (query == null) { 308 | query = new String(""); 309 | } 310 | return gpgmeKeylist(getInternalRepresentation(), query, false); 311 | } 312 | 313 | /** 314 | * Find all keys matching query in keyring. 315 | * 316 | * @param query allows the same expressions as gpg on command line 317 | * @return GnuPGKey array of key objects with all matching keys 318 | * @see com.freiheit.gnupg.GnuPGKey 319 | */ 320 | public GnuPGKey[] searchSecretKeys(String query) throws GnuPGException { 321 | if (query == null) { 322 | query = new String(""); 323 | } 324 | return gpgmeKeylist(getInternalRepresentation(), query, true); 325 | } 326 | 327 | /** 328 | * Encrypt plain text and return ASCII-armored text. 329 | * 330 | * @param recipients array of keys to encrypt to 331 | * @param plain the plain text to be encrypted 332 | * @return String encrypted data in ASCII-armored text 333 | */ 334 | public String encryptToAscii(GnuPGKey[] recipients, String plain) { 335 | final GnuPGData plainData = createDataObject(plain); 336 | final String ret = encryptToAscii(recipients, plainData); 337 | plainData.destroy(); 338 | return ret; 339 | } 340 | 341 | /** 342 | * Encrypt a byte array and return ASCII-armored text. 343 | * 344 | * @param recipients array of keys to encrypt to 345 | * @param plain the byte[] to be encrypted 346 | * @return String encrypted data in ASCII-armored text 347 | */ 348 | public String encryptToAscii(GnuPGKey[] recipients, byte[] plain) { 349 | final GnuPGData plainData = createDataObject(plain); 350 | final String ret = encryptToAscii(recipients, plainData); 351 | plainData.destroy(); 352 | return ret; 353 | } 354 | 355 | /** 356 | * Encrypt plain text and return ASCII-armored text. 357 | * 358 | * @param recipients array of keys to encrypt to 359 | * @param plain the GnuPGData to be encrypted 360 | * @return String encrypted data in ASCII-armored text 361 | */ 362 | public String encryptToAscii(GnuPGKey[] recipients, GnuPGData plain) { 363 | long l = getInternalRepresentation(); 364 | boolean previous = gpgmeGetArmor(l); 365 | gpgmeSetArmor(l, true); 366 | GnuPGData cipher = createDataObject(); 367 | encrypt(recipients, plain, cipher); 368 | final String ret = cipher.toString(); 369 | cipher.destroy(); 370 | if (previous == false) // maintain the original ASCII-Armor state 371 | gpgmeSetArmor(l, false); 372 | return ret; 373 | } 374 | 375 | /** 376 | * Encrypt a byte array and return encrypted data in binary form. 377 | * 378 | * @param recipients array of keys to encrypt to 379 | * @param plain the plain binary data to be encrypted 380 | * @return byte[] encrypted data in binary data 381 | */ 382 | public byte[] encryptToBinary(GnuPGKey[] recipients, byte[] plain) { 383 | final GnuPGData plainData = createDataObject(plain); 384 | final byte[] ret = encryptToBinary(recipients, plainData); 385 | plainData.destroy(); 386 | return ret; 387 | } 388 | 389 | /** 390 | * Encrypt plain text and return encrypted data in binary form. 391 | * 392 | * @param recipients array of keys to encrypt to 393 | * @param plain the plain text to be encrypted 394 | * @return byte[] encrypted data in binary data 395 | */ 396 | public byte[] encryptToBinary(GnuPGKey[] recipients, String plain) { 397 | final GnuPGData plainData = createDataObject(plain); 398 | final byte[] ret = encryptToBinary(recipients, plainData); 399 | plainData.destroy(); 400 | return ret; 401 | } 402 | 403 | /** 404 | * Encrypt plain data and return encrypted data in binary form. 405 | * 406 | * @param recipients array of keys to encrypt to 407 | * @param plain the GnuPGData to be encrypted 408 | * @return String encrypted data in ASCII-armored text 409 | */ 410 | public byte[] encryptToBinary(GnuPGKey[] recipients, GnuPGData plain) { 411 | long l = getInternalRepresentation(); 412 | boolean previous = gpgmeGetArmor(l); 413 | gpgmeSetArmor(l, true); 414 | GnuPGData cipher = createDataObject(); 415 | encrypt(recipients, plain, cipher); 416 | ByteArrayOutputStream baos = new ByteArrayOutputStream(plain.size()); 417 | BufferedOutputStream out = new BufferedOutputStream(baos, 8192); 418 | try { 419 | cipher.write(out); 420 | } catch (IOException e) { 421 | e.printStackTrace(); 422 | } 423 | cipher.destroy(); 424 | if (previous == false) // maintain the original ASCII-Armor state 425 | gpgmeSetArmor(l, false); 426 | return baos.toByteArray(); 427 | } 428 | 429 | /** 430 | * Encrypts the text in plain with the public key of each 431 | * recipient. The result is returned as GnuPGData. 432 | * 433 | * @param recipients array of the keys to encrypt to 434 | * @param plain bytes to be encrypted 435 | * @return GnuPGData the encrypted data 436 | * @see com.freiheit.gnupg.GnuPGData 437 | * @see com.freiheit.gnupg.GnuPGKey 438 | */ 439 | public GnuPGData encrypt(GnuPGKey[] recipients, byte[] plain) 440 | throws GnuPGException { 441 | if (hasNoRecipients(recipients) || plain == null || plain.length == 0) 442 | throw new GnuPGException("Encryption arguments not complete."); 443 | 444 | final GnuPGData plainData = createDataObject(plain); 445 | GnuPGData cipherData = createDataObject(); 446 | 447 | gpgmeOpEncrypt(this.getInternalRepresentation(), 448 | getInternalRepresentationFromRecipients(recipients), 449 | plainData.getInternalRepresentation(), 450 | cipherData.getInternalRepresentation()); 451 | plainData.destroy(); 452 | return cipherData; 453 | } 454 | 455 | /** 456 | * Encrypts the text in plain with the public key of each 457 | * recipient. The result is returned as GnuPGData. 458 | * 459 | * @param recipients array of the keys to encrypt to 460 | * @param plain the text to be encrypted 461 | * @return GnuPGData the encrypted data 462 | * @see com.freiheit.gnupg.GnuPGData 463 | * @see com.freiheit.gnupg.GnuPGKey 464 | */ 465 | public GnuPGData encrypt(GnuPGKey[] recipients, String plain) 466 | throws GnuPGException { 467 | if (hasNoRecipients(recipients) || plain == null || plain.equals("")) 468 | throw new GnuPGException("Encryption arguments not complete."); 469 | 470 | final GnuPGData plainData = createDataObject(plain); 471 | GnuPGData cipherData = createDataObject(); 472 | 473 | gpgmeOpEncrypt(this.getInternalRepresentation(), 474 | getInternalRepresentationFromRecipients(recipients), 475 | plainData.getInternalRepresentation(), 476 | cipherData.getInternalRepresentation()); 477 | plainData.destroy(); 478 | return cipherData; 479 | } 480 | 481 | /** 482 | * Encrypts the data from plain with the public key of each 483 | * recipient. The result is stored in cipher. 484 | * 485 | * @param recipients Array with the public keys of all recipients 486 | * @param plain text, that should be encrypted 487 | * @param cipher text, the encrypted plain text after method call 488 | * @see com.freiheit.gnupg.GnuPGData 489 | * @see com.freiheit.gnupg.GnuPGKey 490 | */ 491 | public void encrypt(GnuPGKey[] recipients, GnuPGData plain, GnuPGData cipher) 492 | throws GnuPGException { 493 | if (hasNoRecipients(recipients) || plain == null || cipher == null) 494 | throw new GnuPGException("Encryption arguments not complete."); 495 | 496 | // note that these are pointers to addresses in the gnupg-for-java 497 | // shared lib 498 | long context = this.getInternalRepresentation(); 499 | if (gpgmeGetSignersLength(context) == 0) 500 | gpgmeOpEncrypt(context, 501 | getInternalRepresentationFromRecipients(recipients), 502 | plain.getInternalRepresentation(), 503 | cipher.getInternalRepresentation()); 504 | else 505 | gpgmeOpEncryptSign(context, 506 | getInternalRepresentationFromRecipients(recipients), 507 | plain.getInternalRepresentation(), 508 | cipher.getInternalRepresentation()); 509 | } 510 | 511 | public void encryptAndSign(GnuPGKey[] recipients, GnuPGData plain, GnuPGData cipher) 512 | throws GnuPGException { 513 | if (hasNoRecipients(recipients) || plain == null || cipher == null) 514 | throw new GnuPGException("Encryption-Arguments not complete."); 515 | 516 | gpgmeOpEncryptSign(this.getInternalRepresentation(), 517 | getInternalRepresentationFromRecipients(recipients), 518 | plain.getInternalRepresentation(), 519 | cipher.getInternalRepresentation()); 520 | } 521 | 522 | /** 523 | * Decrypts the data from cipher and returns the result. 524 | * 525 | * @param cipher the data to be decrypted 526 | * @return plain the resulting decrypted data 527 | * @see com.freiheit.gnupg.GnuPGData 528 | */ 529 | public GnuPGData decrypt(byte[] cipher) throws GnuPGException { 530 | if (cipher == null || cipher.length == 0) 531 | throw new GnuPGException("Encryption arguments not complete."); 532 | 533 | GnuPGData plainData = createDataObject(); 534 | final GnuPGData cipherData = createDataObject(cipher); 535 | 536 | gpgmeOpDecrypt(this.getInternalRepresentation(), 537 | cipherData.getInternalRepresentation(), 538 | plainData.getInternalRepresentation()); 539 | cipherData.destroy(); 540 | return plainData; 541 | } 542 | 543 | /** 544 | * Decrypts the data from cipher and returns the result. 545 | * 546 | * @param cipher the data to be decrypted 547 | * @return plain the resulting decrypted data 548 | * @see com.freiheit.gnupg.GnuPGData 549 | */ 550 | public GnuPGData decrypt(String cipher) throws GnuPGException { 551 | if (cipher == null || cipher.length() == 0) 552 | throw new GnuPGException("Encryption arguments not complete."); 553 | 554 | GnuPGData plainData = createDataObject(); 555 | final GnuPGData cipherData = createDataObject(cipher); 556 | 557 | gpgmeOpDecrypt(this.getInternalRepresentation(), 558 | cipherData.getInternalRepresentation(), 559 | plainData.getInternalRepresentation()); 560 | cipherData.destroy(); 561 | return plainData; 562 | } 563 | 564 | /** 565 | * Decrypts the data from cipher and stores the result in 566 | * plain. 567 | * 568 | * @param cipher text, holds the cipher to be decrypted 569 | * @param plain text, holds the decrypted text after decryption 570 | * @see com.freiheit.gnupg.GnuPGData 571 | */ 572 | public void decrypt(GnuPGData cipher, GnuPGData plain) throws GnuPGException { 573 | if (cipher == null || plain == null) 574 | return; 575 | 576 | gpgmeOpDecrypt(this.getInternalRepresentation(), 577 | cipher.getInternalRepresentation(), plain.getInternalRepresentation()); 578 | } 579 | 580 | /** 581 | * Decrypts the data from cipher and stores the result in 582 | * plain, then verifies the signature of the data. If the 583 | * decryption or verification fails, it throws a GnuPGException 584 | * . 585 | * 586 | * @param cipher holds the data to be decrypted and verified 587 | * @param plain holds the decrypted data after decryption 588 | * @see com.freiheit.gnupg.GnuPGData 589 | */ 590 | public void decryptVerify(GnuPGData cipher, GnuPGData plain) throws GnuPGException { 591 | if (cipher == null || plain == null) 592 | return; 593 | 594 | gpgmeOpDecryptVerify(this.getInternalRepresentation(), 595 | cipher.getInternalRepresentation(), 596 | plain.getInternalRepresentation()); 597 | } 598 | 599 | public void changePassphrase(GnuPGKey key) throws GnuPGException { 600 | if (key == null) 601 | return; 602 | 603 | gpgmeOpChangePassphrase(this.getInternalRepresentation(), key.getInternalRepresentation()); 604 | 605 | } 606 | 607 | /* 608 | * Not finished. Decrypts the data in cipher and verfies the 609 | * signature on the cipher. 610 | * @param cipher encrypted and signed data 611 | * @param plain will contain the result after the method call 612 | */ 613 | // public void decryptAndVerify(GnuPGData cipher, GnuPGData plain) throws 614 | // GnuPGException{ 615 | // if (cipher == null || plain == null) return; 616 | 617 | // gpgmeOpDecryptVerify(this.getInternalRepresentation(), 618 | // cipher.getInternalRepresentation(), plain.getInternalRepresentation()); 619 | // } 620 | 621 | /** 622 | * Signs the data in plain and stores the result in 623 | * signature. 624 | * 625 | * @param plain data that you want to sign 626 | * @param signature result of the operation 627 | */ 628 | public void sign(GnuPGData plain, GnuPGData signature) throws GnuPGException { 629 | if (plain == null || signature == null) 630 | throw new GnuPGException("Parameters not complete or null."); 631 | 632 | gpgmeOpSign(this.getInternalRepresentation(), 633 | plain.getInternalRepresentation(), signature.getInternalRepresentation()); 634 | } 635 | 636 | /** 637 | * Verifies a signature. 638 | * 639 | * @param signature TODO 640 | * @param signed TODO 641 | * @param plain TODO 642 | */ 643 | public void verify(GnuPGData signature, GnuPGData signed, GnuPGData plain) 644 | throws GnuPGException { 645 | if (signature == null || signed == null || plain == null) 646 | throw new GnuPGException("Parameters not complete or null."); 647 | gpgmeOpVerify(this.getInternalRepresentation(), 648 | signature.getInternalRepresentation(), 649 | signed.getInternalRepresentation(), 650 | plain.getInternalRepresentation()); 651 | } 652 | 653 | /** 654 | * Adds a Signer to this context. All signature operation will uses 655 | * this/these signer(s), until you clear the signers from the context. You 656 | * remove all signers at once with a call to clearSigners(). 657 | * 658 | * @param key that should be used for signing operations 659 | * @see com.freiheit.gnupg.GnuPGKey 660 | */ 661 | public void addSigner(GnuPGKey key) throws GnuPGException { 662 | if (key == null) 663 | throw new GnuPGException("Parameters not complete or null."); 664 | gpgmeAddSigners(getInternalRepresentation(), key.getInternalRepresentation()); 665 | } 666 | 667 | /** 668 | * Removes all signers from this context. You add Signers with addSigner(). 669 | */ 670 | public void clearSigners() throws GnuPGException { 671 | gpgmeClearSigners(getInternalRepresentation()); 672 | } 673 | 674 | /** 675 | * Get a specific Signer at a given index. You add Signers with addSigner(). 676 | * 677 | * @param index which signer in the list of Signers 678 | * @return the GnuPGKey at index, or null if it doesn't exist 679 | * @see com.freiheit.gnupg.GnuPGKey 680 | */ 681 | public GnuPGKey getSigner(int index) throws GnuPGException { 682 | return new GnuPGKey(gpgmeGetSigner(getInternalRepresentation(), index)); 683 | } 684 | 685 | /** 686 | * Gets the number of Signers currently in the GnuPGContext. You add Signers 687 | * with addSigner(). 688 | * 689 | * @return long the number of Signers currently in the GnuPGContext 690 | * @see com.freiheit.gnupg.GnuPGKey 691 | */ 692 | public long getSignersLength() throws GnuPGException { 693 | return gpgmeGetSignersLength(getInternalRepresentation()); 694 | } 695 | 696 | /** 697 | * Imports a Key (private or public). You can supply the key in ASCII armor. 698 | */ 699 | public void importKey(GnuPGData keydata) throws GnuPGException { 700 | gpgmeOpImport(getInternalRepresentation(), keydata.getInternalRepresentation()); 701 | } 702 | 703 | /** 704 | * Imports a Key (private or public). You can supply the key in ASCII armor. 705 | */ 706 | public void importKey(File file) throws GnuPGException, IOException { 707 | GnuPGData keydata = createDataObject(file); 708 | if (keydata == null) { 709 | System.out.println("importkey: parsing key data failed"); 710 | return; 711 | } 712 | gpgmeOpImport(getInternalRepresentation(), keydata.getInternalRepresentation()); 713 | } 714 | 715 | /** 716 | * This calls immediately the release method for the context in the 717 | * underlying gpgme library. This method is called by the finalizer of the 718 | * class anyway, but you can call it yourself if you want to get rid of a 719 | * context at once and don't want to wait for the non-deterministic 720 | * garbage-collector of the JVM. 721 | */ 722 | public void destroy() { 723 | if (getInternalRepresentation() != 0) { 724 | gpgmeRelease(getInternalRepresentation()); 725 | setInternalRepresentation(0); 726 | } 727 | } 728 | 729 | /** 730 | * Releases underlying datastructures. Simple calls the destroy() method. 731 | */ 732 | @Override 733 | protected void finalize() { 734 | destroy(); 735 | } 736 | 737 | /** 738 | * Generates a new PGP key and stores it in the keyring. 739 | */ 740 | public void genPgpKey(String params) throws GnuPGException { 741 | gpgmeOpGenKey(getInternalRepresentation(), params); 742 | } 743 | 744 | /** 745 | * Generates a new Key. 746 | */ 747 | public void genKey(String params, GnuPGData pub, GnuPGData secret) throws GnuPGException { 748 | gpgmeOpGenKey(getInternalRepresentation(), params); 749 | } 750 | 751 | /** 752 | * Sets the engine info for the context 753 | */ 754 | public void setEngineInfo(int proto, String fileName, String homeDir) { 755 | 756 | // note that this is a pointer to and address in the gnupg-for-java 757 | // shared 758 | // lib 759 | long ctx = getInternalRepresentation(); 760 | gpgmeCtxSetEngineInfo(ctx, proto, fileName, homeDir); 761 | } 762 | 763 | /** 764 | * Returns the result of a key generation. This must bedirectly called, 765 | * after the key has been generated. 766 | * 767 | * @return the result of a key generation 768 | */ 769 | public GnuPGGenkeyResult getGenkeyResult() { 770 | return gpgmeOpGenkeyResult(getInternalRepresentation()); 771 | 772 | } 773 | 774 | /** 775 | * Export the keys defined by the pattern. 776 | * 777 | * @param pattern pattern for the keys 778 | * @param reserved not used, must be set 0. For later use revered. 779 | * @param data empty data object. Will be filled with the keys. 780 | */ 781 | public void export(String pattern, long reserved, GnuPGData data) { 782 | gpgmeOpExport(getInternalRepresentation(), pattern, 0, data.getInternalRepresentation()); 783 | } 784 | 785 | /** 786 | * Deletes a Key from key ring. When allowSecret, a secret Key will be 787 | * deleted 788 | * 789 | * @param key key to delete 790 | * @param allowSecret if a secret key shall be deleted. 791 | */ 792 | public void delete(GnuPGKey key, boolean allowSecret) { 793 | gpgmeOpDelete(getInternalRepresentation(), key.getInternalRepresentation(), allowSecret); 794 | } 795 | 796 | /* 797 | * Native methods: All these methods are implemented as JNI calls in: 798 | * GnuPGContext.c The naming is as close as possible to the corresponding 799 | * GPGME methods. So, if you want to know what these methods are actually 800 | * doing: Please refer to the GPGME docs. 801 | */ 802 | private native void gpgmeGetEngineInfo(); 803 | 804 | private native long gpgmeNew(); 805 | 806 | private native void gpgmeOpEncrypt(long l, long[] recipientsInternals, long m, long n); 807 | 808 | private native void gpgmeOpDecrypt(long l, long m, long n); 809 | 810 | private native void gpgmeOpChangePassphrase(long l, long m); 811 | 812 | private native void gpgmeRelease(long l); 813 | 814 | private native void gpgmeOpEncryptSign(long context, long[] recipients, long plain, long cipher); 815 | 816 | private native void gpgmeOpDecryptVerify(long context, long cipher, long plain); 817 | 818 | private native void gpgmeOpSign(long context, long l, long m); 819 | 820 | private native void gpgmeOpVerify(long context, long l, long m, long n); 821 | 822 | private native GnuPGKey[] gpgmeKeylist(long l, String query, boolean secret_only); 823 | 824 | private native void gpgmeAddSigners(long l, long m); 825 | 826 | private native void gpgmeClearSigners(long context); 827 | 828 | private native long gpgmeGetSigner(long context, int index); 829 | 830 | private native long gpgmeGetSignersLength(long context); 831 | 832 | private native void gpgmeOpImport(long context, long l); 833 | 834 | private native void gpgmeOpExport(long context, String pattern, long reserved, long l); 835 | 836 | private native void gpgmeOpGenKey(long context, String params); 837 | 838 | private native void gpgmeCtxSetEngineInfo(long context, int proto, String fileName, 839 | String homeDir); 840 | 841 | private native GnuPGGenkeyResult gpgmeOpGenkeyResult(long context); 842 | 843 | private native void gpgmeOpDelete(long context, long l, boolean allowSecret); 844 | 845 | // getters/setters for members, no caching, always direct access to gpgme 846 | private native boolean gpgmeGetArmor(long l); 847 | 848 | private native void gpgmeSetArmor(long l, boolean state); 849 | 850 | private native boolean gpgmeGetTextmode(long l); 851 | 852 | private native void gpgmeSetTextmode(long l, boolean state); 853 | 854 | } 855 | 856 | /* Local Variables: tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil; End: */ 857 | -------------------------------------------------------------------------------- /src/com/freiheit/gnupg/GnuPGData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: GnuPGData.java,v 1.1 2005/01/24 13:56:58 stefan Exp $ 3 | * (c) Copyright 2005 freiheit.com technologies gmbh, Germany. 4 | * 5 | * This file is part of Java for GnuPG (http://www.freiheit.com). 6 | * 7 | * Java for GnuPG is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation; either version 2.1 10 | * of the License, or (at your option) any later version. 11 | * 12 | * Please see COPYING for the complete licence. 13 | */ 14 | 15 | package com.freiheit.gnupg; 16 | 17 | import java.io.ByteArrayOutputStream; 18 | import java.io.File; 19 | import java.io.FileNotFoundException; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.io.OutputStream; 23 | 24 | /** 25 | * Holds the data that you want to work on and stores the results of crypto 26 | * operations. 27 | * 28 | * @author Stefan Richter, stefan@freiheit.com 29 | */ 30 | public class GnuPGData extends GnuPGPeer { 31 | 32 | /** 33 | * Use the factory methods from GnuPGContext to create GnuPGData instances. 34 | * Generates an empty data object. Use this, if you want to create a data 35 | * object to hold a result from a crypto operation. 36 | */ 37 | protected GnuPGData() { 38 | setInternalRepresentation(gpgmeDataNew()); 39 | } 40 | 41 | /** 42 | * Use the factory methods in GnuPGContext to create GnuPGData instances. 43 | * Generates a new data object based on read/write stream access to a file. 44 | * 45 | * @param file your file 46 | * @throws IOException 47 | */ 48 | protected GnuPGData(File file) throws IOException, GnuPGException { 49 | this(file, "r+"); 50 | } 51 | 52 | /** 53 | * Use the factory methods in GnuPGContext to create GnuPGData instances. 54 | * Generates a new data object based on stream access to a file, with 55 | * settable open mode. 56 | * 57 | * @param file your file 58 | * @param mode the POSIX mode to open the file, e.g "r" or "w+" 59 | * @throws IOException 60 | */ 61 | protected GnuPGData(File file, String mode) throws IOException, GnuPGException { 62 | if (file == null || !file.exists()) 63 | throw new FileNotFoundException(); 64 | if (!file.canRead()) 65 | throw new IOException("Cannot read: " + file); 66 | if (!file.canRead()) 67 | throw new IOException("Is a directory: " + file); 68 | setInternalRepresentation(gpgmeDataNewFromFilename(file.getCanonicalPath(), mode)); 69 | } 70 | 71 | /** 72 | * Use the factory methods from GnuPGContext to create GnuPGData instances. 73 | * Generates a new data object containing the given String. 74 | * 75 | * @param str your string 76 | */ 77 | protected GnuPGData(String str) { 78 | this(str.getBytes()); 79 | } 80 | 81 | /** 82 | * Use the factory methods from GnuPGContext to create GnuPGData instances. 83 | * Generates a new Data-Object containing the given byte array. 84 | * 85 | * @param data your data 86 | */ 87 | protected GnuPGData(byte[] data) { 88 | long gpgmeDataNewFromMem = gpgmeDataNewFromMem(data); 89 | setInternalRepresentation(gpgmeDataNewFromMem); 90 | } 91 | 92 | /* 93 | * FIXME: This is not working! Use it, and it will crash the JVM. 94 | */ 95 | public void read(InputStream in) throws IOException { 96 | if (in != null) { 97 | gpgmeDataRead(getInternalRepresentation(), in); 98 | } 99 | } 100 | 101 | /** 102 | * Writes the data/string contained in this data object to the given Java 103 | * OutputStream. 104 | * 105 | * @param out OutputStream, where the data/string should be written 106 | */ 107 | public void write(OutputStream out) throws IOException { 108 | if (out != null) { 109 | gpgmeDataWrite(getInternalRepresentation(), out); 110 | } 111 | } 112 | 113 | /** 114 | * Helper method to print out the data/string from this data object. 115 | * 116 | * @return String representation of the data contained in this data object 117 | * (expect weird results with binary data) 118 | */ 119 | @Override 120 | public String toString() { 121 | String result = null; 122 | ByteArrayOutputStream baos = new ByteArrayOutputStream(this.size()); 123 | try { 124 | this.write(baos); 125 | result = baos.toString(); 126 | } catch (IOException ioe) { 127 | result = ioe.getMessage(); 128 | } 129 | return result; 130 | } 131 | 132 | /** 133 | * This calls immediately the release method for the datastructure in the 134 | * underlying gpgme library. This method is called by the finalizer of the 135 | * class anyway, but you can call it yourself if you want to get rid of this 136 | * datastructure at once and don't want to wait for the non-deterministic 137 | * garbage-collector of the JVM. 138 | */ 139 | public void destroy() { 140 | if (getInternalRepresentation() != 0) { 141 | gpgmeDataRelease(getInternalRepresentation()); 142 | setInternalRepresentation(0); 143 | } 144 | } 145 | 146 | /** 147 | * Releases underlying datastructures. Simple calls the destroy() method. 148 | */ 149 | @Override 150 | protected void finalize() { 151 | destroy(); 152 | } 153 | 154 | public int size() { 155 | return gpgmeSize(getInternalRepresentation()); 156 | } 157 | 158 | private native int gpgmeSize(long l); 159 | 160 | private native long gpgmeDataNewFromMem(byte[] plain); 161 | 162 | private native long gpgmeDataNewFromFilename(String filename, String mode); 163 | 164 | private native long gpgmeDataNew(); 165 | 166 | private native void gpgmeDataWrite(long l, OutputStream out) throws IOException; 167 | 168 | private native void gpgmeDataRelease(long l); 169 | 170 | private native void gpgmeDataRead(long data, InputStream in) throws IOException; 171 | } 172 | 173 | /* Local Variables: tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil; End: */ 174 | -------------------------------------------------------------------------------- /src/com/freiheit/gnupg/GnuPGException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: GnuPGException.java,v 1.1 2005/01/24 13:56:58 stefan Exp $ 3 | * (c) Copyright 2005 freiheit.com technologies gmbh, Germany. 4 | * 5 | * This file is part of Java for GnuPG (http://www.freiheit.com). 6 | * 7 | * Java for GnuPG is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation; either version 2.1 10 | * of the License, or (at your option) any later version. 11 | * 12 | * Please see COPYING for the complete licence. 13 | */ 14 | 15 | package com.freiheit.gnupg; 16 | 17 | /** 18 | * If the underlying gpgme library reports an error, this exception is thrown. 19 | * Wraps all errors messages from inside gpgme. 20 | * 21 | * @author Stefan Richter, stefan@freiheit.com 22 | */ 23 | public class GnuPGException extends RuntimeException { 24 | 25 | private static final long serialVersionUID = -775599686124698560L; 26 | 27 | /** 28 | * This Exception is normally only thrown from within the native part of 29 | * this library. 30 | * 31 | * @param msg is an error message text from gpgme 32 | */ 33 | GnuPGException(String msg) { 34 | super(msg); 35 | } 36 | } 37 | 38 | /* Local Variables: tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil; End: */ 39 | -------------------------------------------------------------------------------- /src/com/freiheit/gnupg/GnuPGGenkeyResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id$ 3 | * (c) Copyright 2005 freiheit.com technologies gmbh, Germany. 4 | * 5 | * This file is part of Java for GnuPG (http://www.freiheit.com). 6 | * 7 | * Java for GnuPG is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation; either version 2.1 10 | * of the License, or (at your option) any later version. 11 | * 12 | * Please see COPYING for the complete licence. 13 | */ 14 | /** 15 | * 16 | */ 17 | 18 | package com.freiheit.gnupg; 19 | 20 | /** 21 | * Class to handle Generate Key Results
22 | * Created on: 23. Mai 06
23 | * 24 | * @author Stefan Neumann 25 | * @version $Id$ 26 | */ 27 | /** 28 | * TODO: DESCRIBE ME
29 | * Created on: 23. Mai 06
30 | * 31 | * @author Stefan Neumann 32 | * @version $Id$ 33 | */ 34 | /** 35 | * TODO: DESCRIBE ME
36 | * Created on: 23. Mai 06
37 | * 38 | * @author Stefan Neumann 39 | * @version $Id$ 40 | */ 41 | public class GnuPGGenkeyResult { 42 | 43 | private String _fpr; 44 | private boolean _primary; 45 | private boolean _sub; 46 | 47 | protected GnuPGGenkeyResult() { 48 | } 49 | 50 | /** 51 | * This is the fingerprint of the key that was created. If both a primary 52 | * and a sub key were generated, the fingerprint of the primary key will be 53 | * returned. If the crypto engine does not provide the fingerprint, `it will 54 | * return a null pointer. 55 | * 56 | * @return fingerprint of the created key 57 | */ 58 | public String getFpr() { 59 | return _fpr; 60 | } 61 | 62 | /** 63 | * This is a flag that is set to true if a primary key was created and to 64 | * false if not. 65 | * 66 | * @return flag, if a primary key was created 67 | */ 68 | public boolean isPrimary() { 69 | return _primary; 70 | } 71 | 72 | /** 73 | * This is a flag that is set to true if a subkey was created and to false 74 | * if not. 75 | * 76 | * @return flag, if a subkey was created 77 | */ 78 | public boolean isSub() { 79 | return _sub; 80 | } 81 | } 82 | 83 | /* Local Variables: tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil; End: */ 84 | -------------------------------------------------------------------------------- /src/com/freiheit/gnupg/GnuPGKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: GnuPGKey.java,v 1.1 2005/01/24 13:56:58 stefan Exp $ 3 | * (c) Copyright 2005 freiheit.com technologies gmbh, Germany. 4 | * 5 | * This file is part of Java for GnuPG (http://www.freiheit.com). 6 | * 7 | * Java for GnuPG is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation; either version 2.1 10 | * of the License, or (at your option) any later version. 11 | * 12 | * Please see COPYING for the complete licence. 13 | */ 14 | 15 | package com.freiheit.gnupg; 16 | 17 | import java.util.ArrayList; 18 | import java.util.Date; 19 | import java.util.Iterator; 20 | import java.util.List; 21 | 22 | /** 23 | * Represents a key. You can manage and find keys using GnuPGContext. You can 24 | * not instantiate a key by yourself. You always need a context. 25 | * 26 | * @see com.freiheit.gnupg.GnuPGContext 27 | * @author Stefan Richter, stefan@freiheit.com 28 | */ 29 | public class GnuPGKey extends GnuPGPeer { 30 | /** 31 | * This constructor is only called from within the JNI routines. This is for 32 | * example used, when a keylist search returns keys. This is how then each 33 | * key is instantiated on the java side from c. 34 | */ 35 | protected GnuPGKey(long ptr) { 36 | // note that this is a pointer to an address in the gnupg-for-java shared lib 37 | setInternalRepresentation(ptr); 38 | } 39 | 40 | /** 41 | * Fetch a public key by its 16 hex char fingerprint String 42 | * 43 | * @param context - the current GnuPGContext 44 | * @param fingerprint - the 16 hex char fingerprint String 45 | */ 46 | protected GnuPGKey(GnuPGContext context, String fingerprint) { 47 | setInternalRepresentation(gpgmeGetKey(context.getInternalRepresentation(), fingerprint, 48 | false)); 49 | } 50 | 51 | /** 52 | * Fetch a key by its 16 hex char fingerprint String 53 | * 54 | * @param context the current GnuPGContext 55 | * @param fingerprint the 16 hex char fingerprint String 56 | * @param secret_only whether to return only secret keys 57 | */ 58 | protected GnuPGKey(GnuPGContext context, String fingerprint, boolean secret_only) { 59 | setInternalRepresentation(gpgmeGetKey(context.getInternalRepresentation(), fingerprint, 60 | secret_only)); 61 | } 62 | 63 | /** 64 | * Get the Name of the default key/userid. 65 | */ 66 | public String getName() { 67 | return gpgmeGetName(getInternalRepresentation()); 68 | } 69 | 70 | /** 71 | * Get the Email-Address of the default key/userid. 72 | */ 73 | public String getEmail() { 74 | return gpgmeGetEmail(getInternalRepresentation()); 75 | } 76 | 77 | /** 78 | * Get the Key-ID of the default key/userid. 79 | */ 80 | public String getKeyID() { 81 | return gpgmeGetKeyID(getInternalRepresentation()); 82 | } 83 | 84 | public Date getTimestamp() { 85 | return new Date(gpgmeGetTimestamp(getInternalRepresentation()) / 1000); 86 | } 87 | 88 | /** 89 | * Get the Fingerprint of the default key/userid. 90 | */ 91 | public String getFingerprint() { 92 | return gpgmeGetFingerprint(getInternalRepresentation()); 93 | } 94 | 95 | /** 96 | * Get the Comment of the default key/userid. 97 | */ 98 | public String getComment() { 99 | return gpgmeGetComment(getInternalRepresentation()); 100 | } 101 | 102 | /** 103 | * Get the User-ID of the default key/userid. 104 | */ 105 | public String getUserID() { 106 | return gpgmeGetUserID(getInternalRepresentation()); 107 | } 108 | 109 | public boolean canEncrypt() { 110 | return gpgmeCanEncrypt(getInternalRepresentation()); 111 | } 112 | 113 | public boolean canSign() { 114 | return gpgmeCanSign(getInternalRepresentation()); 115 | } 116 | 117 | public boolean canCertify() { 118 | return gpgmeCanCertify(getInternalRepresentation()); 119 | } 120 | 121 | public boolean canAuthenticate() { 122 | return gpgmeCanAuthenticate(getInternalRepresentation()); 123 | } 124 | 125 | public boolean isRevoked() { 126 | return gpgmeIsRevoked(getInternalRepresentation()); 127 | } 128 | 129 | public boolean isExpired() { 130 | return gpgmeIsExpired(getInternalRepresentation()); 131 | } 132 | 133 | public boolean isDisabled() { 134 | return gpgmeIsDisabled(getInternalRepresentation()); 135 | } 136 | 137 | public boolean isInvalid() { 138 | return gpgmeIsInvalid(getInternalRepresentation()); 139 | } 140 | 141 | public boolean isQualified() { 142 | return gpgmeIsQualified(getInternalRepresentation()); 143 | } 144 | 145 | public boolean isSecret() { 146 | return gpgmeIsSecret(getInternalRepresentation()); 147 | } 148 | 149 | public boolean hasSecretKey() { 150 | return gpgmeHasSecretKey(getInternalRepresentation()); 151 | } 152 | 153 | /** 154 | * Lists all signatures of the default key/userid. Every key can have 155 | * multiple signatures. Signatures can be incomplete. This means, that not 156 | * all details (name, email-address etc.) were downloaded from a keyserver. 157 | * But you will at least see the key-id of the signature. Use GnuPG to 158 | * --refresh-keys if you want to see all signature details. 159 | *

160 | * Currently I am not supporting java generics for a type safe iterator, 161 | * because there are to many people still using jdk-1.4.x without generics 162 | * support. This will be changed on increasing demand. 163 | *

164 | * 165 | * @return Iterator of GnuPGSignature objects 166 | * @see com.freiheit.gnupg.GnuPGSignature 167 | */ 168 | public Iterator getSignatures() { 169 | List siglist = null; 170 | GnuPGSignature sig = getSignature(); 171 | while (sig != null) { 172 | if (siglist == null) { 173 | siglist = new ArrayList(); 174 | } 175 | siglist.add(sig); 176 | sig = sig.getNextSignature(); 177 | } 178 | if (siglist == null) 179 | return null; 180 | else 181 | return siglist.listIterator(); 182 | } 183 | 184 | /** 185 | * Helper to list signatures in the toString()-method. 186 | */ 187 | private String listSignatures() { 188 | Iterator iter = getSignatures(); 189 | GnuPGSignature sig; 190 | StringBuffer buf = new StringBuffer(); 191 | 192 | while (iter != null && iter.hasNext()) { 193 | sig = iter.next(); 194 | buf.append("\t").append(sig).append("\n"); 195 | } 196 | 197 | return buf.toString(); 198 | } 199 | 200 | /** 201 | * Helper to get the head of the linked list of signatures from the native 202 | * space. 203 | */ 204 | private GnuPGSignature getSignature() { 205 | GnuPGSignature result = null; 206 | 207 | // note that thhis is a pointer to an address in the gnupg-for-java shared 208 | // lib 209 | long ptr = gpgmeGetSignature(getInternalRepresentation()); 210 | 211 | if (ptr != 0) { 212 | result = new GnuPGSignature(ptr); 213 | } 214 | 215 | return result; 216 | } 217 | 218 | /** 219 | * Return this key with all of its signatures. 220 | * 221 | * @return String multiline text with one key and 0..many signatures 222 | */ 223 | public String toString() { 224 | StringBuffer buf = new StringBuffer(); 225 | buf.append(getKeyID()). 226 | append(": "). 227 | append(getName()). 228 | append(", "). 229 | append(getComment()). 230 | append(", "). 231 | append(getEmail()). 232 | append(", "). 233 | append("["). 234 | append(getFingerprint()). 235 | append("]"). 236 | append("\n"). 237 | append(listSignatures()); 238 | return buf.toString(); 239 | } 240 | 241 | /** 242 | * This calls immediately the release method for the datastructure in the 243 | * underlying gpgme library. This method is called by the finalizer of the 244 | * class anyway, but you can call it yourself if you want to get rid of this 245 | * datastructure at once and don't want to wait for the non-deterministic 246 | * garbage-collector of the JVM. 247 | */ 248 | public void destroy() { 249 | if (getInternalRepresentation() != 0) { 250 | gpgmeKeyUnref(getInternalRepresentation()); 251 | setInternalRepresentation(0); 252 | } 253 | } 254 | 255 | /** 256 | * Releases underlying datastructures. Simple calls the destroy() method. 257 | */ 258 | protected void finalize() { 259 | destroy(); 260 | } 261 | 262 | private native long gpgmeGetKey(long context, String fingerprint, boolean secret); 263 | 264 | private native long gpgmeKeyUnref(long keyptr); 265 | 266 | private native String gpgmeGetName(long keyptr); 267 | 268 | private native String gpgmeGetEmail(long keyptr); 269 | 270 | private native String gpgmeGetKeyID(long keyptr); 271 | 272 | private native long gpgmeGetTimestamp(long keyptr); 273 | 274 | private native String gpgmeGetFingerprint(long keyptr); 275 | 276 | private native String gpgmeGetComment(long keyptr); 277 | 278 | private native String gpgmeGetUserID(long keyptr); 279 | 280 | private native long gpgmeGetSignature(long keyptr); 281 | 282 | private native boolean gpgmeCanEncrypt(long keyptr); 283 | 284 | private native boolean gpgmeCanSign(long keyptr); 285 | 286 | private native boolean gpgmeCanCertify(long keyptr); 287 | 288 | private native boolean gpgmeCanAuthenticate(long keyptr); 289 | 290 | private native boolean gpgmeIsRevoked(long keyptr); 291 | 292 | private native boolean gpgmeIsExpired(long keyptr); 293 | 294 | private native boolean gpgmeIsDisabled(long keyptr); 295 | 296 | private native boolean gpgmeIsInvalid(long keyptr); 297 | 298 | private native boolean gpgmeIsQualified(long keyptr); 299 | 300 | private native boolean gpgmeIsSecret(long keyptr); 301 | 302 | private native boolean gpgmeHasSecretKey(long keyptr); 303 | 304 | } 305 | 306 | /* Local Variables: tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil; End: */ 307 | -------------------------------------------------------------------------------- /src/com/freiheit/gnupg/GnuPGPeer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: GnuPGPeer.java,v 1.1 2005/01/24 13:56:58 stefan Exp $ 3 | * (c) Copyright 2005 freiheit.com technologies gmbh, Germany. 4 | * 5 | * This file is part of Java for GnuPG (http://www.freiheit.com). 6 | * 7 | * Java for GnuPG is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation; either version 2.1 10 | * of the License, or (at your option) any later version. 11 | * 12 | * Please see COPYING for the complete licence. 13 | */ 14 | 15 | package com.freiheit.gnupg; 16 | 17 | /** 18 | * Peer Class to hold the pointers to connect to the underlying gpgme library. 19 | * This is the base class for all GnuPG*.java Classes. DO NOT USE IT. It is not 20 | * intended for library users. 21 | * 22 | * @author Stefan Richter, stefan@freiheit.com 23 | */ 24 | public class GnuPGPeer { 25 | // note that this is a pointer to an address in the gnupg-for-java shared lib 26 | protected long _internalRepresentation; 27 | 28 | /** 29 | * DO NOT USE IT. This is only use from inside the library. 30 | */ 31 | protected void setInternalRepresentation(long ptr) { 32 | // note that this is a pointer to an address in the gnupg-for-java shared lib 33 | _internalRepresentation = ptr; 34 | } 35 | 36 | /** 37 | * DO NOT USE IT. This is only use from inside the library. 38 | */ 39 | protected long getInternalRepresentation() { 40 | // note that this is a pointer to an address in the gnupg-for-java shared lib 41 | return _internalRepresentation; 42 | } 43 | } 44 | 45 | /* Local Variables: tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil; End: */ 46 | -------------------------------------------------------------------------------- /src/com/freiheit/gnupg/GnuPGSignature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: GnuPGSignature.java,v 1.1 2005/01/24 13:56:58 stefan Exp $ 3 | * (c) Copyright 2005 freiheit.com technologies gmbh, Germany. 4 | * 5 | * This file is part of Java for GnuPG (http://www.freiheit.com). 6 | * 7 | * Java for GnuPG is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation; either version 2.1 10 | * of the License, or (at your option) any later version. 11 | * 12 | * Please see COPYING for the complete licence. 13 | */ 14 | 15 | package com.freiheit.gnupg; 16 | 17 | /** 18 | * Represents a signature from a key. A signature doesn't stand alone. It is 19 | * always bound to a key. So if you want to see a signature, you first have to 20 | * get a key via the GnuPGContext. 21 | *

22 | * This class accesses directly the corresponding structure "under the hood" and 23 | * stores no data in java members. This means, that every call of a method also 24 | * results in a native call to access gpgme memory. 25 | * 26 | * @author Stefan Richter, stefan@freiheit.com 27 | * @see com.freiheit.gnupg.GnuPGContext 28 | */ 29 | public class GnuPGSignature extends GnuPGPeer { 30 | 31 | /** 32 | * This constructor is only called from GnuPGKey. It is called when the lib 33 | * browses thru the linked list of signatures of each key. 34 | * 35 | * @see com.freiheit.gnupg.GnuPGKey 36 | */ 37 | protected GnuPGSignature(long ptr) { 38 | // note that this is a pointer to an address in the gnupg-for-java shared lib 39 | setInternalRepresentation(ptr); 40 | } 41 | 42 | /** 43 | * Is signature key revoked? 44 | * 45 | * @return true, if revoked 46 | */ 47 | public boolean isRevoked() { 48 | return gpgmeGetRevoked(getInternalRepresentation()); 49 | } 50 | 51 | /** 52 | * Is signature key expired? 53 | * 54 | * @return true, if expired 55 | */ 56 | public boolean isExpired() { 57 | return gpgmeGetExpired(getInternalRepresentation()); 58 | } 59 | 60 | /** 61 | * Is signature key invalid? 62 | * 63 | * @return true, if invalid 64 | */ 65 | public boolean isInvalid() { 66 | return gpgmeGetInvalid(getInternalRepresentation()); 67 | } 68 | 69 | /** 70 | * Is signature key exportable? 71 | * 72 | * @return true, if exportable 73 | */ 74 | public boolean isExportable() { 75 | return gpgmeGetExportable(getInternalRepresentation()); 76 | } 77 | 78 | /** 79 | * Returns Key-ID of signature key. 80 | * 81 | * @return Key-ID 82 | */ 83 | public String getKeyID() { 84 | return gpgmeGetKeyID(getInternalRepresentation()); 85 | } 86 | 87 | /** 88 | * Returns User-ID of signer. 89 | * 90 | * @return User-ID 91 | */ 92 | public String getUserID() { 93 | return gpgmeGetUserID(getInternalRepresentation()); 94 | } 95 | 96 | /** 97 | * Returns Name of signer. 98 | * 99 | * @return Name 100 | */ 101 | public String getName() { 102 | return gpgmeGetName(getInternalRepresentation()); 103 | } 104 | 105 | /** 106 | * Returns Email-Address of signer. 107 | * 108 | * @return Email-Address 109 | */ 110 | public String getEmail() { 111 | return gpgmeGetEmail(getInternalRepresentation()); 112 | } 113 | 114 | /** 115 | * Returns Comment. 116 | * 117 | * @return Comment 118 | */ 119 | public String getComment() { 120 | return gpgmeGetComment(getInternalRepresentation()); 121 | } 122 | 123 | /** 124 | * Checks, if all signature details are available. 125 | * 126 | * @return true, if more info than the keyid is available 127 | */ 128 | public boolean hasDetails() { 129 | return !getName().equals(""); 130 | } 131 | 132 | /** 133 | * String-Representation of this Signature. 134 | * 135 | * @return String single line of text with name, comment etc. 136 | */ 137 | public String toString() { 138 | StringBuffer buf = new StringBuffer(); 139 | buf.append(getKeyID()); 140 | if (hasDetails()) { 141 | buf.append(", "); 142 | buf.append(getName()); 143 | buf.append(", "); 144 | buf.append(getComment()); 145 | buf.append(", "); 146 | buf.append(getEmail()); 147 | } 148 | else { 149 | buf.append(" "); 150 | } 151 | return buf.toString(); 152 | } 153 | 154 | /** 155 | * Gets the next pointer in the gpgme_key_sig_t structure. 156 | * 157 | * @return new GnuPGSignature-Object 158 | */ 159 | protected GnuPGSignature getNextSignature() { 160 | GnuPGSignature result = null; 161 | 162 | // note that this is a pointer to an address in the gnupg-for-java shared lib 163 | long next = gpgmeGetNextSignature(getInternalRepresentation()); 164 | 165 | if (next != 0) { 166 | result = new GnuPGSignature(next); 167 | } 168 | 169 | return result; 170 | } 171 | 172 | // native method declarations: 173 | private native boolean gpgmeGetRevoked(long l); 174 | 175 | private native boolean gpgmeGetExpired(long l); 176 | 177 | private native boolean gpgmeGetInvalid(long l); 178 | 179 | private native boolean gpgmeGetExportable(long l); 180 | 181 | private native String gpgmeGetKeyID(long l); 182 | 183 | private native String gpgmeGetUserID(long l); 184 | 185 | private native String gpgmeGetName(long l); 186 | 187 | private native String gpgmeGetEmail(long l); 188 | 189 | private native String gpgmeGetComment(long l); 190 | 191 | private native long gpgmeGetNextSignature(long l); 192 | 193 | } 194 | 195 | /* Local Variables: tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil; End: */ 196 | -------------------------------------------------------------------------------- /src/com/freiheit/gnupg/package.html: -------------------------------------------------------------------------------- 1 | 2 | Main package. 3 |

4 | Java for GnuPG is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public Licenseas published by the Free Software Foundation; either version 2.1 6 | of the License, or (at your option) any later version. 7 |

8 | Please see COPYING in the source distribution for the complete licence. 9 |

10 | 11 | -------------------------------------------------------------------------------- /src/com/freiheit/gnupg/tests/GnuPGTestSuite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: GnuPGTestSuite.java,v 1.3 2006/06/14 15:53:12 sneumann Exp $ 3 | * (c) Copyright 2005 freiheit.com technologies gmbh, Germany. 4 | * 5 | * This file is part of Java for GnuPG (http://www.freiheit.com). 6 | * 7 | * Java for GnuPG is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License 9 | * as published by the Free Software Foundation; either version 2.1 10 | * of the License, or (at your option) any later version. 11 | * 12 | * Please see COPYING for the complete licence. 13 | */ 14 | 15 | package com.freiheit.gnupg.tests; 16 | 17 | import java.util.Iterator; 18 | 19 | import junit.framework.Test; 20 | import junit.framework.TestCase; 21 | import junit.framework.TestSuite; 22 | 23 | import com.freiheit.gnupg.GnuPGContext; 24 | import com.freiheit.gnupg.GnuPGData; 25 | import com.freiheit.gnupg.GnuPGKey; 26 | import com.freiheit.gnupg.GnuPGSignature; 27 | 28 | /** 29 | * I will improve this TestSuite later, that everybody can run it without 30 | * specific fingerprints. It should behave like the tests in gpgme. 31 | *

32 | * But the tests can also be seen as code examples. 33 | * 34 | * @author Stefan Richter, stefan@freiheit.com 35 | */ 36 | public class GnuPGTestSuite extends TestCase { 37 | 38 | private static String HOME = "/tmp/gnupg-for-java-tests"; 39 | private static String PLAINTEXT = "I am a not so secret text."; 40 | // Currently, you can not run these test without these fingerprints. 41 | // And: You need to know the passphrases...forget it. 42 | // but you could add your own fingerprints... 43 | private static String CD_FPR = "1C12878CFAA2ECDC81DC43DB12262834A6123FF6"; 44 | // private static String SR_FPR = "F05F385DFA40962D0075AB9C2B80170D"; 45 | private static String SR_FPR = "BE54B261FDDF09025D249CAF948C94764B9A38DB"; 46 | 47 | // private static GnuPGKey person1 = null; 48 | // private static GnuPGKey person2 = null; 49 | 50 | public static Test suite() { 51 | System.out.println("suite()"); 52 | TestSuite suite = new TestSuite(GnuPGTestSuite.class); 53 | GnuPGContext ctx = getContext(); 54 | 55 | String person1Key = " \n" + 56 | "Key-Type: DSA\n" + 57 | "Key-Length: 1024\n" + 58 | "Subkey-Type: ELG-E\n" + 59 | "Subkey-Length: 1024\n" + 60 | "Name-Real: alpha\n" + 61 | "Name-Comment: just a test\n" + 62 | "Name-Email: alpha@alpha.org\n" + 63 | "Expire-Date: 0\n" + 64 | "Passphrase: alpha\n" + 65 | ""; 66 | ctx.genKey(person1Key, null, null); 67 | // String fpr1 = ctx.getGenkeyResult().getFpr(); 68 | 69 | String person2Key = " \n" + 70 | "Key-Type: DSA\n" + 71 | "Key-Length: 1024\n" + 72 | "Subkey-Type: ELG-E\n" + 73 | "Subkey-Length: 1024\n" + 74 | "Name-Real: beta\n" + 75 | "Name-Comment: just a test\n" + 76 | "Name-Email: beta@beta.org\n" + 77 | "Expire-Date: 0\n" + 78 | "Passphrase: beta\n" + 79 | ""; 80 | ctx.genKey(person2Key, null, null); 81 | // String fpr2 = ctx.getGenkeyResult().getFpr(); 82 | 83 | System.out.println("done suite()"); 84 | return suite; 85 | } 86 | 87 | public static GnuPGContext getContext() { 88 | GnuPGContext ctx = new GnuPGContext(); 89 | ctx.setEngineInfo(ctx.getProtocol(), ctx.getFilename(), HOME); 90 | return ctx; 91 | } 92 | 93 | public void testEngine() { 94 | GnuPGContext ctx = new GnuPGContext(); 95 | ctx.getVersion(); 96 | ctx.getFilename(); 97 | ctx.getRequiredVersion(); 98 | } 99 | 100 | public void testContextSetterAndGetter() { 101 | GnuPGContext ctx = new GnuPGContext(); 102 | 103 | // Test set/isArmor() 104 | assertTrue(ctx.isArmor());// default: true 105 | ctx.setArmor(false); 106 | assertFalse(ctx.isArmor()); 107 | ctx.setArmor(true); 108 | assertTrue(ctx.isArmor()); 109 | 110 | // Test set/isTextmode() 111 | assertTrue(ctx.isTextmode());// default: true 112 | ctx.setTextmode(false); 113 | assertFalse(ctx.isTextmode()); 114 | ctx.setTextmode(true); 115 | assertTrue(ctx.isTextmode()); 116 | } 117 | 118 | public void testKeySearch() { 119 | GnuPGContext ctx = new GnuPGContext(); 120 | GnuPGKey[] keys = ctx.searchKeys("stefan"); 121 | 122 | assertNotNull(keys); 123 | 124 | for (int i = 0; keys != null && i < keys.length; i++) { 125 | assertNotNull(keys[i]); 126 | Iterator iter = keys[i].getSignatures(); 127 | System.out.println(keys[i]);// Uncomment to print each key 128 | while (iter.hasNext()) { 129 | assertNotNull((GnuPGSignature) iter.next()); 130 | } 131 | } 132 | } 133 | 134 | public void testEncryptForOneRecipient() { 135 | GnuPGContext ctx = new GnuPGContext(); 136 | GnuPGData plain = ctx.createDataObject(PLAINTEXT); 137 | GnuPGData cipher = ctx.createDataObject(); 138 | 139 | GnuPGKey[] recipient = ctx.generateEmptyKeyArray(1); 140 | recipient[0] = ctx.getKeyByFingerprint(SR_FPR); 141 | 142 | ctx.encrypt(recipient, plain, cipher); 143 | 144 | assertNotNull(cipher.toString()); 145 | } 146 | 147 | public void testEncryptForTwoRecipients() { 148 | GnuPGContext ctx = new GnuPGContext(); 149 | GnuPGData plain = ctx.createDataObject(PLAINTEXT); 150 | GnuPGData cipher = ctx.createDataObject(); 151 | 152 | GnuPGKey[] recipients = ctx.generateEmptyKeyArray(2); 153 | recipients[0] = ctx.getKeyByFingerprint(SR_FPR); 154 | recipients[1] = ctx.getKeyByFingerprint(CD_FPR); 155 | 156 | ctx.encrypt(recipients, plain, cipher); 157 | 158 | assertNotNull(cipher.toString()); 159 | } 160 | 161 | public void testDecryptFromOneRecipient() { 162 | GnuPGContext ctx = new GnuPGContext(); 163 | GnuPGData plain = ctx.createDataObject(PLAINTEXT); 164 | GnuPGData cipher = ctx.createDataObject(); 165 | GnuPGData decrypted = ctx.createDataObject(); 166 | 167 | GnuPGKey[] recipient = ctx.generateEmptyKeyArray(1); 168 | recipient[0] = ctx.getKeyByFingerprint(SR_FPR); 169 | 170 | ctx.encrypt(recipient, plain, cipher); 171 | ctx.decrypt(cipher, decrypted); 172 | 173 | assertNotNull(decrypted.toString()); 174 | assertEquals(decrypted.toString(), PLAINTEXT); 175 | } 176 | 177 | public void testAddAndClearSigners() { 178 | GnuPGContext ctx = new GnuPGContext(); 179 | GnuPGKey signer1 = ctx.getKeyByFingerprint(SR_FPR); 180 | GnuPGKey signer2 = ctx.getKeyByFingerprint(CD_FPR); 181 | 182 | ctx.addSigner(signer1); 183 | ctx.addSigner(signer2); 184 | ctx.clearSigners(); 185 | } 186 | 187 | public void testSign() { 188 | GnuPGContext ctx = new GnuPGContext(); 189 | GnuPGData plain = ctx.createDataObject(PLAINTEXT); 190 | GnuPGData signature = ctx.createDataObject(); 191 | 192 | GnuPGKey signer = ctx.getKeyByFingerprint(SR_FPR); 193 | ctx.addSigner(signer); 194 | ctx.sign(plain, signature); 195 | 196 | System.out.println(plain.toString()); 197 | System.out.println(signature.toString()); 198 | 199 | assertNotNull(signature.toString()); 200 | } 201 | 202 | public void testEncrypt() { 203 | GnuPGContext ctx = new GnuPGContext(); 204 | 205 | String plaintext = "HALLLLLLLLLLO"; 206 | System.out.println("plaintext: " + plaintext); 207 | GnuPGData plain = ctx.createDataObject(plaintext); 208 | System.out.println("plain (from data object): \"" + plain.toString() + "\""); 209 | GnuPGData encrypted = ctx.createDataObject(); 210 | 211 | GnuPGKey[] recipients = ctx.generateEmptyKeyArray(1); 212 | recipients[0] = ctx.getKeyByFingerprint(SR_FPR); 213 | 214 | ctx.encrypt(recipients, plain, encrypted); 215 | 216 | System.out.println("encrypted (from data object: \"" + encrypted.toString() + "\""); 217 | 218 | String encStr = encrypted.toString(); 219 | 220 | assertNotNull(encStr); 221 | assertFalse("Encrypted message cannot be empty.", encStr.length() == 0); 222 | 223 | } 224 | 225 | // public void testEncryptAndSign(){ 226 | // GnuPGContext ctx = new GnuPGContext(); 227 | // ctx.setPassphraseListener(new GnuPGPassphraseWindow()); 228 | // GnuPGData plain = new GnuPGData(PLAINTEXT); 229 | // GnuPGData cipher = new GnuPGData(); 230 | // 231 | // GnuPGKey[] recipient = ctx.generateEmptyKeyArray(1); 232 | // recipient[0] = ctx.getKeyByFingerprint(SR_FPR); 233 | // 234 | // ctx.addSigner(recipient[0]); 235 | // 236 | // ctx.encryptAndSign(recipient, plain, cipher); 237 | // 238 | // assertNotNull(cipher.toString()); 239 | // } 240 | // 241 | // public void testDecryptAndVerify(){ 242 | // GnuPGContext ctx = new GnuPGContext(); 243 | // ctx.setPassphraseListener(new GnuPGPassphraseWindow()); 244 | // GnuPGData plain = new GnuPGData(PLAINTEXT); 245 | // GnuPGData cipher = new GnuPGData(); 246 | // GnuPGData decrypted = new GnuPGData(); 247 | // 248 | // GnuPGKey[] recipient = ctx.generateEmptyKeyArray(1); 249 | // recipient[0] = ctx.getKeyByFingerprint(SR_FPR); 250 | // 251 | // ctx.addSigner(recipient[0]); 252 | // 253 | // ctx.encryptAndSign(recipient, plain, cipher); 254 | // 255 | // ctx.decryptAndVerify(cipher, decrypted); 256 | // 257 | // assertNotNull(decrypted.toString()); 258 | // } 259 | 260 | // public void testGenKey(){ 261 | // final String dirName = "/home/stefan/tmp/.gnupg"; 262 | // GnuPGContext ctx = new GnuPGContext(); 263 | // System.err.println("Proto: "+ ctx.getProtocol()); 264 | // ctx.setEngineInfo(ctx.getProtocol(),ctx.getFilename(),dirName); 265 | // String keyText=" \n"+ 266 | // "Key-Type: DSA\n"+ 267 | // "Key-Length: 1024\n"+ 268 | // "Subkey-Type: ELG-E\n"+ 269 | // "Subkey-Length: 1024\n"+ 270 | // "Name-Real: Binding Test\n"+ 271 | // "Name-Comment: with stupid passphrase\n"+ 272 | // "Name-Email: bind@foo.bar\n"+ 273 | // "Expire-Date: 0\n"+ 274 | // "Passphrase: abc\n"+ 275 | // ""; 276 | // ctx.genKey(keyText,null,null); 277 | // GnuPGGenkeyResult genkeyResult = ctx.getGenkeyResult(); 278 | // GnuPGKey[] keys = ctx.searchKeys("binding"); 279 | // assertNotNull(keys); 280 | // assertEquals("Fingerprint are not equal!",keys[0].getFingerprint(),genkeyResult.getFpr()); 281 | // assertTrue(genkeyResult.isPrimary()); 282 | // assertTrue(genkeyResult.isSub()); 283 | // File dir = new File(dirName); 284 | // dir.deleteOnExit(); 285 | // 286 | // } 287 | 288 | } 289 | 290 | /* Local Variables: tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil; End: */ 291 | -------------------------------------------------------------------------------- /tests/android-signing-key.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/android-signing-key.p12 -------------------------------------------------------------------------------- /tests/icon-encrypted-not-signed.png.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/icon-encrypted-not-signed.png.gpg -------------------------------------------------------------------------------- /tests/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/icon.png -------------------------------------------------------------------------------- /tests/icon.png.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP MESSAGE----- 2 | Version: GnuPG v1.4.11 (GNU/Linux) 3 | Comment: GPGTools - http://gpgtools.org 4 | 5 | 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 212 | IKzU4PSn8n8A 213 | =jw1k 214 | -----END PGP MESSAGE----- 215 | -------------------------------------------------------------------------------- /tests/icon.png.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/icon.png.gpg -------------------------------------------------------------------------------- /tests/icon.png.sig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/icon.png.sig -------------------------------------------------------------------------------- /tests/one-public-key.pkr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/one-public-key.pkr -------------------------------------------------------------------------------- /tests/public-keys.pkr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/public-keys.pkr -------------------------------------------------------------------------------- /tests/public-keys.pkr.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP SIGNATURE----- 2 | Version: GnuPG v1.4.11 (GNU/Linux) 3 | Comment: GPGTools - http://gpgtools.org 4 | 5 | iQIcBAABCAAGBQJR32MjAAoJEJ8P5Yc3S76BkOQQAIxFNiKR03Dv5cI5jpRhFFR7 6 | eVx3JXT1lJL342F41XKuDAy79PoCu5/Wx3smVXV76LWNcDVW9UWhywVJUQYYq0iL 7 | 7yLYA+KdcMuFpZW/SbpnLyKgUlvw9FesUO1Y6W1f4BOSNIJmUwqvAXOKFngV2kQI 8 | 5p9hua9jpY9v+iz16ctGvQvbwWlRS+0qU7nnSfv4r0i8U7a/PD47UftZW+mQn/aa 9 | UD8EWS7PzSPHHeakqzo8lp8HYrjK0u44izpIOwDAugOkWy97Fe6y/qvzGuVszVWC 10 | KcC9isfFHCkn5HnGsoSb2oOeqNXwoJVgQTw5Q8z9E/ZbOPFXvr2Y5eQYv6pCkvq/ 11 | S8GuWnNtQYUU7nN127HzD956oq9yq/4Q28jeeCsvyzH4Uji7g6RaxuHVp9nzoQzI 12 | cpxuNR5wMG83nsFpmSjoKKkt43sFsVa0EY/tOlZ+nSBG3zz7vR6XWK+pbLhpwu4t 13 | JHtNqL65xyCH3ItgEUoxYMeUZFieWTzEjaPgAHdd1f46P3idnchgOqPvhXYQrOob 14 | CMH9BSttSslkrvynZI/iSj5vU+NH+ptm3+qpZ3fQ0gcmCaKkY6ige5dlDK/t1Bd2 15 | 0dPoqFJdg00hX04sFVIlbu138osG762xfy6BkqUvUQIfUaFeFf3phCmebwmTRI/0 16 | HJOBT9+804m6uIdtwqi0 17 | =woib 18 | -----END PGP SIGNATURE----- 19 | -------------------------------------------------------------------------------- /tests/public-keys.pkr.sig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/public-keys.pkr.sig -------------------------------------------------------------------------------- /tests/pubring.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/pubring.gpg -------------------------------------------------------------------------------- /tests/secret: -------------------------------------------------------------------------------- 1 | Attack across river at dawn. 2 | -------------------------------------------------------------------------------- /tests/secret-keys.skr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/secret-keys.skr -------------------------------------------------------------------------------- /tests/secret.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/secret.gpg -------------------------------------------------------------------------------- /tests/secring.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/secring.gpg -------------------------------------------------------------------------------- /tests/trustdb.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guardianproject/gnupg-for-java/f5b4d5b92ece838598f25e493a6075d2a70fe91e/tests/trustdb.gpg --------------------------------------------------------------------------------