From 89673dfd2dd7c8b60bfdc6ce37d154ac84515398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Tue, 31 Mar 2015 19:30:30 +0200 Subject: [PATCH] Replace AndroidPinning submodule by checked in code --- .gitmodules | 4 - extern/AndroidPinning | 1 - extern/AndroidPinning/AndroidManifest.xml | 9 + extern/AndroidPinning/LICENSE | 621 ++++++++++++++++++ extern/AndroidPinning/build.gradle | 30 + extern/AndroidPinning/project.properties | 2 + extern/AndroidPinning/res/raw/cacerts | Bin 0 -> 138259 bytes .../ssl/pinning/CertificateChainCleaner.java | 89 +++ .../ssl/pinning/PinningSSLSocketFactory.java | 166 +++++ .../ssl/pinning/PinningTrustManager.java | 199 ++++++ .../ssl/pinning/SystemKeyStore.java | 138 ++++ .../ssl/pinning/util/PinningHelper.java | 111 ++++ 12 files changed, 1365 insertions(+), 5 deletions(-) delete mode 160000 extern/AndroidPinning create mode 100644 extern/AndroidPinning/AndroidManifest.xml create mode 100644 extern/AndroidPinning/LICENSE create mode 100644 extern/AndroidPinning/build.gradle create mode 100644 extern/AndroidPinning/project.properties create mode 100644 extern/AndroidPinning/res/raw/cacerts create mode 100644 extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/CertificateChainCleaner.java create mode 100644 extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/PinningSSLSocketFactory.java create mode 100644 extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/PinningTrustManager.java create mode 100644 extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/SystemKeyStore.java create mode 100644 extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/util/PinningHelper.java diff --git a/.gitmodules b/.gitmodules index 251cd3fd4..e593b54d7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,10 +6,6 @@ path = extern/MemorizingTrustManager url = https://github.com/ge0rg/MemorizingTrustManager.git ignore = dirty -[submodule "extern/AndroidPinning"] - path = extern/AndroidPinning - url = https://gitlab.com/fdroid/androidpinning.git - ignore = dirty [submodule "extern/libsuperuser"] path = extern/libsuperuser url = https://github.com/Chainfire/libsuperuser diff --git a/extern/AndroidPinning b/extern/AndroidPinning deleted file mode 160000 index d8c0143e1..000000000 --- a/extern/AndroidPinning +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d8c0143e18ab3abb693300fe4dfbcd05907f7536 diff --git a/extern/AndroidPinning/AndroidManifest.xml b/extern/AndroidPinning/AndroidManifest.xml new file mode 100644 index 000000000..b144f02b6 --- /dev/null +++ b/extern/AndroidPinning/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/extern/AndroidPinning/LICENSE b/extern/AndroidPinning/LICENSE new file mode 100644 index 000000000..94a045322 --- /dev/null +++ b/extern/AndroidPinning/LICENSE @@ -0,0 +1,621 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS diff --git a/extern/AndroidPinning/build.gradle b/extern/AndroidPinning/build.gradle new file mode 100644 index 000000000..eb3943582 --- /dev/null +++ b/extern/AndroidPinning/build.gradle @@ -0,0 +1,30 @@ +buildscript { + repositories { + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:1.0.0' + } +} + +apply plugin: 'android-library' + +android { + compileSdkVersion 17 + buildToolsVersion '17.0.0' + + android { + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = ['src'] + resources.srcDirs = ['src'] + aidl.srcDirs = ['src'] + renderscript.srcDirs = ['src'] + res.srcDirs = ['res'] + assets.srcDirs = ['assets'] + } + } + } +} diff --git a/extern/AndroidPinning/project.properties b/extern/AndroidPinning/project.properties new file mode 100644 index 000000000..8b1b48694 --- /dev/null +++ b/extern/AndroidPinning/project.properties @@ -0,0 +1,2 @@ +target=android-17 +android.library=true diff --git a/extern/AndroidPinning/res/raw/cacerts b/extern/AndroidPinning/res/raw/cacerts new file mode 100644 index 0000000000000000000000000000000000000000..88517c036c19815ca8a02e9d7d225183f2b2ca8a GIT binary patch literal 138259 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�^y%SG{3(bTln}_z+AgB|x7*;Nhote@ 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 B<~aZW literal 0 HcmV?d00001 diff --git a/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/CertificateChainCleaner.java b/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/CertificateChainCleaner.java new file mode 100644 index 000000000..7b6112f15 --- /dev/null +++ b/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/CertificateChainCleaner.java @@ -0,0 +1,89 @@ +/** + * Copyright (C) 2011-2013 Moxie Marlinspike + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.thoughtcrime.ssl.pinning; + +import java.security.GeneralSecurityException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.LinkedList; + +/** + * Does the work of cleaning up a certificate chain by sifting out any + * unrelated certificates and returning something that's signed from + * EE to a trust anchor. + * + * @author Moxie Marlinspike + */ +class CertificateChainCleaner { + + private CertificateChainCleaner() {} + + public static X509Certificate[] getCleanChain(X509Certificate[] chain, + SystemKeyStore systemKeyStore) + throws CertificateException + { + final LinkedList cleanChain = new LinkedList(); + boolean trustedChain = false; + int i; + + if (systemKeyStore.isTrustRoot(chain[0])) { + trustedChain = true; + } + + cleanChain.add(chain[0]); + + for (i = 1; i < chain.length; i++) { + if (systemKeyStore.isTrustRoot(chain[i])) { + trustedChain = true; + } + + if (isValidLink(chain[i], chain[i - 1])) { + cleanChain.add(chain[i]); + } else { + break; + } + } + + final X509Certificate trustRoot = systemKeyStore.getTrustRootFor(chain[i - 1]); + + if (trustRoot != null) { + cleanChain.add(trustRoot); + trustedChain = true; + } + + if (trustedChain) { + return cleanChain.toArray(new X509Certificate[cleanChain.size()]); + } else { + throw new CertificateException("Didn't find a trust anchor in chain cleanup!"); + } + } + + private static boolean isValidLink(X509Certificate parent, X509Certificate child) { + if (!parent.getSubjectX500Principal().equals(child.getIssuerX500Principal())) { + return false; + } + + try { + child.verify(parent.getPublicKey()); + } catch (GeneralSecurityException gse) { + return false; + } + + return true; + } +} diff --git a/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/PinningSSLSocketFactory.java b/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/PinningSSLSocketFactory.java new file mode 100644 index 000000000..c8a2dd3c1 --- /dev/null +++ b/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/PinningSSLSocketFactory.java @@ -0,0 +1,166 @@ +/** + * Copyright (C) 2011-2013 Moxie Marlinspike + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.thoughtcrime.ssl.pinning; + +import android.content.Context; + +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.conn.ssl.X509HostnameVerifier; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.TrustManager; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; + +/** + * A standard Apache SSL Socket Factory that uses an pinning trust manager. + *

+ * To use: + *

+ *
+ * String[] pins                = new String[] {"40c5401d6f8cbaf08b00edefb1ee87d005b3b9cd"};
+ * SchemeRegistry schemeRegistry = new SchemeRegistry();
+ * schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+ * schemeRegistry.register(new Scheme("https", new PinningSSLSocketFactory(getContext(),pins, 0), 443));
+ *
+ * HttpParams httpParams                     = new BasicHttpParams();
+ * ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
+ * DefaultHttpClient httpClient              = new DefaultHttpClient(connectionManager, httpParams);
+ *
+ * HttpResponse response = httpClient.execute(new HttpGet("https://www.google.com/"));
+ *
+ * 
+ *

+ * + * @author Moxie Marlinspike + */ +public class PinningSSLSocketFactory extends SSLSocketFactory { + + private final javax.net.ssl.SSLSocketFactory pinningSocketFactory; + + /** + * Constructs a PinningSSLSocketFactory with a set of valid pins. + * + * @param pins An array of encoded pins to match a seen certificate + * chain against. A pin is a hex-encoded hash of a X.509 certificate's + * SubjectPublicKeyInfo. A pin can be generated using the provided pin.py + * script: python ./tools/pin.py certificate_file.pem + * + * @param enforceUntilTimestampMillis A timestamp (in milliseconds) when pins will stop being + * enforced. Normal non-pinned certificate validation + * will continue. Set this to some period after your build + * date, or to 0 to enforce pins forever. + */ + + public PinningSSLSocketFactory(Context context, String[] pins, long enforceUntilTimestampMillis) + throws UnrecoverableKeyException, KeyManagementException, + NoSuchAlgorithmException, KeyStoreException + { + super(null); + + final SystemKeyStore keyStore = SystemKeyStore.getInstance(context); + final SSLContext pinningSslContext = SSLContext.getInstance(TLS); + final TrustManager[] pinningTrustManagers = initializePinningTrustManagers(keyStore, pins, enforceUntilTimestampMillis); + + pinningSslContext.init(null, pinningTrustManagers, null); + this.pinningSocketFactory = pinningSslContext.getSocketFactory(); + } + + @Override + public Socket createSocket() throws IOException { + return pinningSocketFactory.createSocket(); + } + + @Override + public Socket connectSocket(final Socket sock, final String host, final int port, + final InetAddress localAddress, int localPort, + final HttpParams params) throws IOException { + final SSLSocket sslSock = (SSLSocket) ((sock != null) ? sock : createSocket()); + + if ((localAddress != null) || (localPort > 0)) { + if (localPort < 0) { + localPort = 0; + } + + sslSock.bind(new InetSocketAddress(localAddress, localPort)); + } + + final int connTimeout = HttpConnectionParams.getConnectionTimeout(params); + final int soTimeout = HttpConnectionParams.getSoTimeout(params); + + final InetSocketAddress remoteAddress = new InetSocketAddress(host, port); + sslSock.connect(remoteAddress, connTimeout); + sslSock.setSoTimeout(soTimeout); + + try { + SSLSocketFactory.STRICT_HOSTNAME_VERIFIER.verify(host, sslSock); + } catch (IOException iox) { + try { + sslSock.close(); + } catch (Exception ignored) { + } + throw iox; + } + + return sslSock; + } + + @Override + public Socket createSocket(final Socket socket, final String host, + int port, final boolean autoClose) + throws IOException + { + if (port == -1) { + port = 443; + } + + final SSLSocket sslSocket = (SSLSocket) pinningSocketFactory.createSocket(socket, host, port, autoClose); + SSLSocketFactory.STRICT_HOSTNAME_VERIFIER.verify(host, sslSocket); + return sslSocket; + } + + @Override + public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) { + throw new IllegalArgumentException("Only strict hostname verification (default) " + + "is supported!"); + } + + @Override + public X509HostnameVerifier getHostnameVerifier() { + return SSLSocketFactory.STRICT_HOSTNAME_VERIFIER; + } + + private TrustManager[] initializePinningTrustManagers(SystemKeyStore keyStore, + String[] pins, + long enforceUntilTimestampMillis) + { + final TrustManager[] trustManagers = new TrustManager[1]; + trustManagers[0] = new PinningTrustManager(keyStore, pins, enforceUntilTimestampMillis); + + return trustManagers; + } +} diff --git a/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/PinningTrustManager.java b/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/PinningTrustManager.java new file mode 100644 index 000000000..7e19ca86b --- /dev/null +++ b/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/PinningTrustManager.java @@ -0,0 +1,199 @@ +/** + * Copyright (C) 2011-2013 Moxie Marlinspike + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.thoughtcrime.ssl.pinning; + +import android.util.Log; + +import java.security.KeyStoreException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +/** + * A TrustManager implementation that enforces Certificate "pins." + * + *

+ * PinningTrustManager is layered on top of the system's default TrustManager, + * such that the system continues to validate CA signatures for SSL connections + * as usual. Additionally, however, PinningTrustManager will enforce certificate + * constraints on the validated certificate chain. Specifically, it + * will ensure that one of an arbitrary number of specified SubjectPublicKeyInfos + * appears somewhere in the valid certificate chain. + *

+ *

+ * To use: + *

+ * TrustManager[] trustManagers = new TrustManager[1];
+ * trustManagers[0] = new PinningTrustManager(SystemKeyStore.getInstance(),
+ *                                            new String[] {"f30012bbc18c231ac1a44b788e410ce754182513"},
+ *                                            0);
+ *
+ * SSLContext sslContext = SSLContext.getInstance("TLS");
+ * sslContext.init(null, trustManagers, null);
+ *
+ * HttpsURLConnection urlConnection = (HttpsURLConnection)new URL("https://encrypted.google.com/").openConnection();
+ * urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
+ * InputStream in = urlConnection.getInputStream();
+ * 
+ *

+ * + * @author Moxie Marlinspike + */ +public class PinningTrustManager implements X509TrustManager { + + private final TrustManager[] systemTrustManagers; + private final SystemKeyStore systemKeyStore; + private final long enforceUntilTimestampMillis; + + private final List pins = new LinkedList(); + private final Set cache = Collections.synchronizedSet(new HashSet()); + + /** + * Constructs a PinningTrustManager with a set of valid pins. + * + * @param keyStore A SystemKeyStore that validation will be based on. + * + * @param pins An array of encoded pins to match a seen certificate + * chain against. A pin is a hex-encoded hash of a X.509 certificate's + * SubjectPublicKeyInfo. A pin can be generated using the provided pin.py + * script: python ./tools/pin.py certificate_file.pem + * + * @param enforceUntilTimestampMillis A timestamp (in milliseconds) when pins will stop being + * enforced. Normal non-pinned certificate validation + * will continue. Set this to some period after your build + * date, or to 0 to enforce pins forever. + */ + public PinningTrustManager(SystemKeyStore keyStore, String[] pins, long enforceUntilTimestampMillis) { + this.systemTrustManagers = initializeSystemTrustManagers(keyStore); + this.systemKeyStore = keyStore; + this.enforceUntilTimestampMillis = enforceUntilTimestampMillis; + + for (String pin : pins) { + this.pins.add(hexStringToByteArray(pin)); + } + } + + private TrustManager[] initializeSystemTrustManagers(SystemKeyStore keyStore) { + try { + final TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509"); + tmf.init(keyStore.trustStore); + + return tmf.getTrustManagers(); + } catch (NoSuchAlgorithmException nsae) { + throw new AssertionError(nsae); + } catch (KeyStoreException e) { + throw new AssertionError(e); + } + } + + private boolean isValidPin(X509Certificate certificate) throws CertificateException { + try { + final MessageDigest digest = MessageDigest.getInstance("SHA1"); + final byte[] spki = certificate.getPublicKey().getEncoded(); + final byte[] pin = digest.digest(spki); + + for (byte[] validPin : this.pins) { + if (Arrays.equals(validPin, pin)) { + return true; + } + } + + return false; + } catch (NoSuchAlgorithmException nsae) { + throw new CertificateException(nsae); + } + } + + private void checkSystemTrust(X509Certificate[] chain, String authType) + throws CertificateException { + for (TrustManager systemTrustManager : systemTrustManagers) { + ((X509TrustManager) systemTrustManager).checkServerTrusted(chain, authType); + } + } + + private void checkPinTrust(X509Certificate[] chain) + throws CertificateException { + + if (enforceUntilTimestampMillis != 0 && + System.currentTimeMillis() > enforceUntilTimestampMillis) + { + Log.w("PinningTrustManager", "Certificate pins are stale, falling back to system trust."); + return; + } + + final X509Certificate[] cleanChain = CertificateChainCleaner.getCleanChain(chain, systemKeyStore); + + for (X509Certificate certificate : cleanChain) { + if (isValidPin(certificate)) { + return; + } + } + + throw new CertificateException("No valid pins found in chain!"); + } + + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + throw new CertificateException("Client certificates not supported!"); + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException + { + if (cache.contains(chain[0])) { + return; + } + + // Note: We do this so that we'll never be doing worse than the default + // system validation. It's duplicate work, however, and can be factored + // out if we make the verification below more complete. + checkSystemTrust(chain, authType); + checkPinTrust(chain); + cache.add(chain[0]); + } + + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + private byte[] hexStringToByteArray(String s) { + final int len = s.length(); + final byte[] data = new byte[len / 2]; + + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + + Character.digit(s.charAt(i + 1), 16)); + } + + return data; + } + + public void clearCache() { + cache.clear(); + } +} diff --git a/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/SystemKeyStore.java b/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/SystemKeyStore.java new file mode 100644 index 000000000..3c013b5de --- /dev/null +++ b/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/SystemKeyStore.java @@ -0,0 +1,138 @@ +/** + * Copyright (C) 2011-2013 Moxie Marlinspike + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.thoughtcrime.ssl.pinning; + +import android.content.Context; +import android.content.res.Resources.NotFoundException; +import android.util.Log; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.Principal; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Enumeration; +import java.util.HashMap; + +/** + * An interface to the system's trust anchors. We're using our + * own truststore, which is just the AOSP default, but in a place + * we know to find it for sure. + * + * @author Moxie Marlinspike + */ +public class SystemKeyStore { + private static final int CACERTS_FILE_SIZE = 1024 * 140; + + private static SystemKeyStore instance; + + public static synchronized SystemKeyStore getInstance(Context context) { + if (instance == null) { + instance = new SystemKeyStore(context); + } + return instance; + } + + private final HashMap trustRoots; + final KeyStore trustStore; + + private SystemKeyStore(Context context) { + final KeyStore trustStore = getTrustStore(context); + this.trustRoots = initializeTrustedRoots(trustStore); + this.trustStore = trustStore; + } + + public boolean isTrustRoot(X509Certificate certificate) { + final X509Certificate trustRoot = trustRoots.get(certificate.getSubjectX500Principal()); + return trustRoot != null && trustRoot.getPublicKey().equals(certificate.getPublicKey()); + } + + public X509Certificate getTrustRootFor(X509Certificate certificate) { + final X509Certificate trustRoot = trustRoots.get(certificate.getIssuerX500Principal()); + + if (trustRoot == null) { + return null; + } + + if (trustRoot.getSubjectX500Principal().equals(certificate.getSubjectX500Principal())) { + return null; + } + + try { + certificate.verify(trustRoot.getPublicKey()); + } catch (GeneralSecurityException e) { + return null; + } + + return trustRoot; + } + + private HashMap initializeTrustedRoots(KeyStore trustStore) { + try { + final HashMap trusted = + new HashMap(); + + for (Enumeration aliases = trustStore.aliases(); aliases.hasMoreElements(); ) { + final String alias = aliases.nextElement(); + final X509Certificate cert = (X509Certificate) trustStore.getCertificate(alias); + + if (cert != null) { + trusted.put(cert.getSubjectX500Principal(), cert); + } + } + + return trusted; + } catch (KeyStoreException e) { + throw new AssertionError(e); + } + } + + private KeyStore getTrustStore(Context context) { + try { + final KeyStore trustStore = KeyStore.getInstance("BKS"); + final BufferedInputStream bin = + new BufferedInputStream(context.getResources().openRawResource(R.raw.cacerts), + CACERTS_FILE_SIZE); + + try { + trustStore.load(bin, "changeit".toCharArray()); + } finally { + try { + bin.close(); + } catch (IOException ioe) { + Log.w("SystemKeyStore", ioe); + } + } + + return trustStore; + } catch (KeyStoreException kse) { + throw new AssertionError(kse); + } catch (NoSuchAlgorithmException e) { + throw new AssertionError(e); + } catch (CertificateException e) { + throw new AssertionError(e); + } catch (NotFoundException e) { + throw new AssertionError(e); + } catch (IOException e) { + throw new AssertionError(e); + } + } +} diff --git a/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/util/PinningHelper.java b/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/util/PinningHelper.java new file mode 100644 index 000000000..10135eb26 --- /dev/null +++ b/extern/AndroidPinning/src/org/thoughtcrime/ssl/pinning/util/PinningHelper.java @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2011-2013 Moxie Marlinspike + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.thoughtcrime.ssl.pinning.util; + +import android.content.Context; + +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpParams; +import org.thoughtcrime.ssl.pinning.PinningSSLSocketFactory; +import org.thoughtcrime.ssl.pinning.PinningTrustManager; +import org.thoughtcrime.ssl.pinning.SystemKeyStore; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import java.io.IOException; +import java.net.URL; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; + +public class PinningHelper { + + /** + * Constructs an HttpClient that will validate SSL connections with a PinningTrustManager. + * + * @param pins An array of encoded pins to match a seen certificate + * chain against. A pin is a hex-encoded hash of a X.509 certificate's + * SubjectPublicKeyInfo. A pin can be generated using the provided pin.py + * script: python ./tools/pin.py certificate_file.pem + */ + + public static HttpClient getPinnedHttpClient(Context context, String[] pins) { + try { + SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + schemeRegistry.register(new Scheme("https", new PinningSSLSocketFactory(context, pins, 0), 443)); + + HttpParams httpParams = new BasicHttpParams(); + ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry); + return new DefaultHttpClient(connectionManager, httpParams); + } catch (UnrecoverableKeyException e) { + throw new AssertionError(e); + } catch (KeyManagementException e) { + throw new AssertionError(e); + } catch (NoSuchAlgorithmException e) { + throw new AssertionError(e); + } catch (KeyStoreException e) { + throw new AssertionError(e); + } + } + + /** + * Constructs an HttpsURLConnection that will validate HTTPS connections against a set of + * specified pins. + * + * @param pins An array of encoded pins to match a seen certificate + * chain against. A pin is a hex-encoded hash of a X.509 certificate's + * SubjectPublicKeyInfo. A pin can be generated using the provided pin.py + * script: python ./tools/pin.py certificate_file.pem + * + */ + + public static HttpsURLConnection getPinnedHttpsURLConnection(Context context, String[] pins, URL url) + throws IOException + { + try { + if (!url.getProtocol().equals("https")) { + throw new IllegalArgumentException("Attempt to construct pinned non-https connection!"); + } + + TrustManager[] trustManagers = new TrustManager[1]; + trustManagers[0] = new PinningTrustManager(SystemKeyStore.getInstance(context), pins, 0); + + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustManagers, null); + + HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection(); + urlConnection.setSSLSocketFactory(sslContext.getSocketFactory()); + + return urlConnection; + } catch (NoSuchAlgorithmException nsae) { + throw new AssertionError(nsae); + } catch (KeyManagementException e) { + throw new AssertionError(e); + } + } +}