APPLE PUBLIC SOURCE LICENSE
-Version 2.0 - August 6, 2003
+Version 1.1 - April 19,1999
Please read this License carefully before downloading this software.
-By downloading or using this software, you are agreeing to be bound by
-the terms of this License. If you do not or cannot agree to the terms
-of this License, please do not download or use the software.
-
-1. General; Definitions. This License applies to any program or other
-work which Apple Computer, Inc. ("Apple") makes publicly available and
-which contains a notice placed by Apple identifying such program or
-work as "Original Code" and stating that it is subject to the terms of
-this Apple Public Source License version 2.0 ("License"). As used in
-this License:
-
-1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is
+By downloading and using this software, you are agreeing to be bound
+by the terms of this License. If you do not or cannot agree to the
+terms of this License, please do not download or use the software.
+
+1. General; Definitions. This License applies to any program or other
+work which Apple Computer, Inc. ("Apple") publicly announces as
+subject to this Apple Public Source License and which contains a
+notice placed by Apple identifying such program or work as "Original
+Code" and stating that it is subject to the terms of this Apple Public
+Source License version 1.1 (or subsequent version thereof), as it may
+be revised from time to time by Apple ("License"). As used in this
+License:
+
+1.1 "Affected Original Code" means only those specific portions of
+Original Code that allegedly infringe upon any party's intellectual
+property rights or are otherwise the subject of a claim of
+infringement.
+
+1.2 "Applicable Patent Rights" mean: (a) in the case where Apple is
the grantor of rights, (i) claims of patents that are now or hereafter
acquired, owned by or assigned to Apple and (ii) that cover subject
matter contained in the Original Code, but only to the extent
owned by or assigned to You and (ii) that cover subject matter in Your
Modifications, taken alone or in combination with Original Code.
-1.2 "Contributor" means any person or entity that creates or
-contributes to the creation of Modifications.
-
1.3 "Covered Code" means the Original Code, Modifications, the
combination of Original Code and any Modifications, and/or any
respective portions thereof.
-1.4 "Externally Deploy" means: (a) to sublicense, distribute or
-otherwise make Covered Code available, directly or indirectly, to
-anyone other than You; and/or (b) to use Covered Code, alone or as
-part of a Larger Work, in any way to provide a service, including but
-not limited to delivery of content, through electronic communication
-with a client other than You.
+1.4 "Deploy" means to use, sublicense or distribute Covered Code other
+than for Your internal research and development (R&D), and includes
+without limitation, any and all internal use or distribution of
+Covered Code within Your business or organization except for R&D use,
+as well as direct or indirect sublicensing or distribution of Covered
+Code by You to any third party in any form or manner.
1.5 "Larger Work" means a work which combines Covered Code or portions
thereof with code not governed by the terms of this License.
1.6 "Modifications" mean any addition to, deletion from, and/or change
-to, the substance and/or structure of the Original Code, any previous
-Modifications, the combination of Original Code and any previous
-Modifications, and/or any respective portions thereof. When code is
+to, the substance and/or structure of Covered Code. When code is
released as a series of files, a Modification is: (a) any addition to
or deletion from the contents of a file containing Covered Code;
and/or (b) any new file or other representation of computer program
(object code).
1.9 "You" or "Your" means an individual or a legal entity exercising
-rights under this License. For legal entities, "You" or "Your"
+rights under this License. For legal entities, "You" or "Your"
includes any entity which controls, is controlled by, or is under
common control with, You, where "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
(50%) or more of the outstanding shares or beneficial ownership of
such entity.
-2. Permitted Uses; Conditions & Restrictions. Subject to the terms
+2. Permitted Uses; Conditions & Restrictions. Subject to the terms
and conditions of this License, Apple hereby grants You, effective on
the date You accept this License and download the Original Code, a
-world-wide, royalty-free, non-exclusive license, to the extent of
+world-wide, royalty-free, non- exclusive license, to the extent of
Apple's Applicable Patent Rights and copyrights covering the Original
Code, to do the following:
-2.1 Unmodified Code. You may use, reproduce, display, perform,
-internally distribute within Your organization, and Externally Deploy
-verbatim, unmodified copies of the Original Code, for commercial or
-non-commercial purposes, provided that in each instance:
-
-(a) You must retain and reproduce in all copies of Original Code the
-copyright and other proprietary notices and disclaimers of Apple as
-they appear in the Original Code, and keep intact all notices in the
-Original Code that refer to this License; and
-
-(b) You must include a copy of this License with every copy of Source
-Code of Covered Code and documentation You distribute or Externally
-Deploy, and You may not offer or impose any terms on such Source Code
-that alter or restrict this License or the recipients' rights
-hereunder, except as permitted under Section 6.
-
-2.2 Modified Code. You may modify Covered Code and use, reproduce,
-display, perform, internally distribute within Your organization, and
-Externally Deploy Your Modifications and Covered Code, for commercial
-or non-commercial purposes, provided that in each instance You also
-meet all of these conditions:
-
-(a) You must satisfy all the conditions of Section 2.1 with respect to
-the Source Code of the Covered Code;
-
-(b) You must duplicate, to the extent it does not already exist, the
-notice in Exhibit A in each file of the Source Code of all Your
-Modifications, and cause the modified files to carry prominent notices
-stating that You changed the files and the date of any change; and
-
-(c) If You Externally Deploy Your Modifications, You must make
-Source Code of all Your Externally Deployed Modifications either
-available to those to whom You have Externally Deployed Your
-Modifications, or publicly available. Source Code of Your Externally
-Deployed Modifications must be released under the terms set forth in
-this License, including the license grants set forth in Section 3
-below, for as long as you Externally Deploy the Covered Code or twelve
-(12) months from the date of initial External Deployment, whichever is
-longer. You should preferably distribute the Source Code of Your
-Externally Deployed Modifications electronically (e.g. download from a
-web site).
-
-2.3 Distribution of Executable Versions. In addition, if You
-Externally Deploy Covered Code (Original Code and/or Modifications) in
-object code, executable form only, You must include a prominent
-notice, in the code itself as well as in related documentation,
-stating that Source Code of the Covered Code is available under the
-terms of this License with information on how and where to obtain such
-Source Code.
-
-2.4 Third Party Rights. You expressly acknowledge and agree that
-although Apple and each Contributor grants the licenses to their
-respective portions of the Covered Code set forth herein, no
-assurances are provided by Apple or any Contributor that the Covered
-Code does not infringe the patent or other intellectual property
-rights of any other entity. Apple and each Contributor disclaim any
-liability to You for claims brought by any other entity based on
-infringement of intellectual property rights or otherwise. As a
-condition to exercising the rights and licenses granted hereunder, You
-hereby assume sole responsibility to secure any other intellectual
-property rights needed, if any. For example, if a third party patent
-license is required to allow You to distribute the Covered Code, it is
-Your responsibility to acquire that license before distributing the
-Covered Code.
-
-3. Your Grants. In consideration of, and as a condition to, the
-licenses granted to You under this License, You hereby grant to any
-person or entity receiving or distributing Covered Code under this
-License a non-exclusive, royalty-free, perpetual, irrevocable license,
-under Your Applicable Patent Rights and other intellectual property
-rights (other than patent) owned or controlled by You, to use,
-reproduce, display, perform, modify, sublicense, distribute and
-Externally Deploy Your Modifications of the same scope and extent as
-Apple's licenses under Sections 2.1 and 2.2 above.
-
-4. Larger Works. You may create a Larger Work by combining Covered
+2.1 You may use, copy, modify and distribute Original Code, with or
+without Modifications, solely for Your internal research and
+development, provided that You must in each instance:
+
+(a) retain and reproduce in all copies of Original Code the copyright
+and other proprietary notices and disclaimers of Apple as they appear
+in the Original Code, and keep intact all notices in the Original Code
+that refer to this License;
+
+(b) include a copy of this License with every copy of Source Code of
+Covered Code and documentation You distribute, and You may not offer
+or impose any terms on such Source Code that alter or restrict this
+License or the recipients' rights hereunder, except as permitted under
+Section 6; and
+
+(c) completely and accurately document all Modifications that you have
+made and the date of each such Modification, designate the version of
+the Original Code you used, prominently include a file carrying such
+information with the Modifications, and duplicate the notice in
+Exhibit A in each file of the Source Code of all such Modifications.
+
+2.2 You may Deploy Covered Code, provided that You must in each
+ instance:
+
+(a) satisfy all the conditions of Section 2.1 with respect to the
+Source Code of the Covered Code;
+
+(b) make all Your Deployed Modifications publicly available in Source
+Code form via electronic distribution (e.g. download from a web site)
+under the terms of this License and subject to the license grants set
+forth in Section 3 below, and any additional terms You may choose to
+offer under Section 6. You must continue to make the Source Code of
+Your Deployed Modifications available for as long as you Deploy the
+Covered Code or twelve (12) months from the date of initial
+Deployment, whichever is longer;
+
+(c) if You Deploy Covered Code containing Modifications made by You,
+inform others of how to obtain those Modifications by filling out and
+submitting the information found at
+http://www.apple.com/publicsource/modifications.html, if available;
+and
+
+(d) if You Deploy Covered Code in object code, executable form only,
+include a prominent notice, in the code itself as well as in related
+documentation, stating that Source Code of the Covered Code is
+available under the terms of this License with information on how and
+where to obtain such Source Code.
+
+3. Your Grants. In consideration of, and as a condition to, the
+licenses granted to You under this License:
+
+(a) You hereby grant to Apple and all third parties a non-exclusive,
+royalty-free license, under Your Applicable Patent Rights and other
+intellectual property rights owned or controlled by You, to use,
+reproduce, modify, distribute and Deploy Your Modifications of the
+same scope and extent as Apple's licenses under Sections 2.1 and 2.2;
+and
+
+(b) You hereby grant to Apple and its subsidiaries a non-exclusive,
+worldwide, royalty-free, perpetual and irrevocable license, under Your
+Applicable Patent Rights and other intellectual property rights owned
+or controlled by You, to use, reproduce, execute, compile, display,
+perform, modify or have modified (for Apple and/or its subsidiaries),
+sublicense and distribute Your Modifications, in any form, through
+multiple tiers of distribution.
+
+4. Larger Works. You may create a Larger Work by combining Covered
Code with other code not governed by the terms of this License and
-distribute the Larger Work as a single product. In each such instance,
-You must make sure the requirements of this License are fulfilled for
-the Covered Code or any portion thereof.
+distribute the Larger Work as a single product. In each such
+instance, You must make sure the requirements of this License are
+fulfilled for the Covered Code or any portion thereof.
-5. Limitations on Patent License. Except as expressly stated in
+5. Limitations on Patent License. Except as expressly stated in
Section 2, no other patent rights, express or implied, are granted by
-Apple herein. Modifications and/or Larger Works may require additional
-patent licenses from Apple which Apple may grant in its sole
-discretion.
-
-6. Additional Terms. You may choose to offer, and to charge a fee for,
-warranty, support, indemnity or liability obligations and/or other
-rights consistent with the scope of the license granted herein
-("Additional Terms") to one or more recipients of Covered Code.
-However, You may do so only on Your own behalf and as Your sole
-responsibility, and not on behalf of Apple or any Contributor. You
-must obtain the recipient's agreement that any such Additional Terms
-are offered by You alone, and You hereby agree to indemnify, defend
-and hold Apple and every Contributor harmless for any liability
-incurred by or claims asserted against Apple or such Contributor by
-reason of any such Additional Terms.
-
-7. Versions of the License. Apple may publish revised and/or new
-versions of this License from time to time. Each version will be given
-a distinguishing version number. Once Original Code has been published
-under a particular version of this License, You may continue to use it
-under the terms of that version. You may also choose to use such
-Original Code under the terms of any subsequent version of this
-License published by Apple. No one other than Apple has the right to
+Apple herein. Modifications and/or Larger Works may require
+additional patent licenses from Apple which Apple may grant in its
+sole discretion.
+
+6. Additional Terms. You may choose to offer, and to charge a fee
+for, warranty, support, indemnity or liability obligations and/or
+other rights consistent with the scope of the license granted herein
+("Additional Terms") to one or more recipients of Covered
+Code. However, You may do so only on Your own behalf and as Your sole
+responsibility, and not on behalf of Apple. You must obtain the
+recipient's agreement that any such Additional Terms are offered by
+You alone, and You hereby agree to indemnify, defend and hold Apple
+harmless for any liability incurred by or claims asserted against
+Apple by reason of any such Additional Terms.
+
+7. Versions of the License. Apple may publish revised and/or new
+versions of this License from time to time. Each version will be
+given a distinguishing version number. Once Original Code has been
+published under a particular version of this License, You may continue
+to use it under the terms of that version. You may also choose to use
+such Original Code under the terms of any subsequent version of this
+License published by Apple. No one other than Apple has the right to
modify the terms applicable to Covered Code created under this
License.
-8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in
-part pre-release, untested, or not fully tested works. The Covered
-Code may contain errors that could cause failures or loss of data, and
-may be incomplete or contain inaccuracies. You expressly acknowledge
-and agree that use of the Covered Code, or any portion thereof, is at
-Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND
-WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND
-APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE
-PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM
-ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT
-NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF
-MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR
-PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD
-PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST
-INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE
-FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS,
-THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR
-ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO
-ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE
-AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY.
-You acknowledge that the Covered Code is not intended for use in the
-operation of nuclear facilities, aircraft navigation, communication
-systems, or air traffic control machines in which case the failure of
-the Covered Code could lead to death, personal injury, or severe
-physical or environmental damage.
-
-9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
-EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL,
-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING
-TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR
-ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY,
-TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF
-APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY
-REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF
-INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY
-TO YOU. In no event shall Apple's total liability to You for all
-damages (other than as may be required by applicable law) under this
-License exceed the amount of fifty dollars ($50.00).
-
-10. Trademarks. This License does not grant any rights to use the
-trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS",
-"QuickTime", "QuickTime Streaming Server" or any other trademarks,
-service marks, logos or trade names belonging to Apple (collectively
-"Apple Marks") or to any trademark, service mark, logo or trade name
-belonging to any Contributor. You agree not to use any Apple Marks in
-or as part of the name of products derived from the Original Code or
-to endorse or promote products derived from the Original Code other
-than as expressly permitted by and in strict compliance at all times
-with Apple's third party trademark usage guidelines which are posted
-at http://www.apple.com/legal/guidelinesfor3rdparties.html.
-
-11. Ownership. Subject to the licenses granted under this License,
-each Contributor retains all rights, title and interest in and to any
-Modifications made by such Contributor. Apple retains all rights,
-title and interest in and to the Original Code and any Modifications
-made by or on behalf of Apple ("Apple Modifications"), and such Apple
-Modifications will not be automatically subject to this License. Apple
-may, at its sole discretion, choose to license such Apple
-Modifications under this License, or on different terms from those
-contained in this License or may choose not to license them at all.
+8. NO WARRANTY OR SUPPORT. The Original Code may contain in whole or
+in part pre-release, untested, or not fully tested works. The
+Original Code may contain errors that could cause failures or loss of
+data, and may be incomplete or contain inaccuracies. You expressly
+acknowledge and agree that use of the Original Code, or any portion
+thereof, is at Your sole and entire risk. THE ORIGINAL CODE IS
+PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND
+AND APPLE AND APPLE'S LICENSOR(S) (FOR THE PURPOSES OF SECTIONS 8 AND
+9, APPLE AND APPLE'S LICENSOR(S) ARE COLLECTIVELY REFERRED TO AS
+"APPLE") EXPRESSLY DISCLAIM ALL WARRANTIES AND/OR CONDITIONS, EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+AND/OR CONDITIONS OF MERCHANTABILITY OR SATISFACTORY QUALITY AND
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
+RIGHTS. APPLE DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE
+ORIGINAL CODE WILL MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF
+THE ORIGINAL CODE WILL BE UNINTERRUPTED OR ERROR- FREE, OR THAT
+DEFECTS IN THE ORIGINAL CODE WILL BE CORRECTED. NO ORAL OR WRITTEN
+INFORMATION OR ADVICE GIVEN BY APPLE OR AN APPLE AUTHORIZED
+REPRESENTATIVE SHALL CREATE A WARRANTY OR IN ANY WAY INCREASE THE
+SCOPE OF THIS WARRANTY. You acknowledge that the Original Code is not
+intended for use in the operation of nuclear facilities, aircraft
+navigation, communication systems, or air traffic control machines in
+which case the failure of the Original Code could lead to death,
+personal injury, or severe physical or environmental damage.
+
+9. Liability.
+
+9.1 Infringement. If any portion of, or functionality implemented by,
+the Original Code becomes the subject of a claim of infringement,
+Apple may, at its option: (a) attempt to procure the rights necessary
+for Apple and You to continue using the Affected Original Code; (b)
+modify the Affected Original Code so that it is no longer infringing;
+or (c) suspend Your rights to use, reproduce, modify, sublicense and
+distribute the Affected Original Code until a final determination of
+the claim is made by a court or governmental administrative agency of
+competent jurisdiction and Apple lifts the suspension as set forth
+below. Such suspension of rights will be effective immediately upon
+Apple's posting of a notice to such effect on the Apple web site that
+is used for implementation of this License. Upon such final
+determination being made, if Apple is legally able, without the
+payment of a fee or royalty, to resume use, reproduction,
+modification, sublicensing and distribution of the Affected Original
+Code, Apple will lift the suspension of rights to the Affected
+Original Code by posting a notice to such effect on the Apple web site
+that is used for implementation of this License. If Apple suspends
+Your rights to Affected Original Code, nothing in this License shall
+be construed to restrict You, at Your option and subject to applicable
+law, from replacing the Affected Original Code with non-infringing
+code or independently negotiating for necessary rights from such third
+party.
+
+9.2 LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES SHALL APPLE BE
+LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF OR RELATING TO THIS LICENSE OR YOUR USE OR INABILITY TO
+USE THE ORIGINAL CODE, OR ANY PORTION THEREOF, WHETHER UNDER A THEORY
+OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY
+OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF
+ANY REMEDY. In no event shall Apple's total liability to You for all
+damages under this License exceed the amount of fifty dollars
+($50.00).
+
+10. Trademarks. This License does not grant any rights to use the
+trademarks or trade names "Apple", "Apple Computer", "Mac OS X", "Mac
+OS X Server" or any other trademarks or trade names belonging to Apple
+(collectively "Apple Marks") and no Apple Marks may be used to endorse
+or promote products derived from the Original Code other than as
+permitted by and in strict compliance at all times with Apple's third
+party trademark usage guidelines which are posted at
+http://www.apple.com/legal/guidelinesfor3rdparties.html.
+
+11. Ownership. Apple retains all rights, title and interest in and to
+the Original Code and any Modifications made by or on behalf of Apple
+("Apple Modifications"), and such Apple Modifications will not be
+automatically subject to this License. Apple may, at its sole
+discretion, choose to license such Apple Modifications under this
+License, or on different terms from those contained in this License or
+may choose not to license them at all. Apple's development, use,
+reproduction, modification, sublicensing and distribution of Covered
+Code will not be subject to this License.
12. Termination.
-12.1 Termination. This License and the rights granted hereunder will
-terminate:
+12.1 Termination. This License and the rights granted hereunder will
+ terminate:
(a) automatically without notice from Apple if You fail to comply with
any term(s) of this License and fail to cure such breach within 30
-days of becoming aware of such breach;
-
-(b) immediately in the event of the circumstances described in Section
-13.5(b); or
-
-(c) automatically without notice from Apple if You, at any time during
-the term of this License, commence an action for patent infringement
-against Apple; provided that Apple did not first commence
-an action for patent infringement against You in that instance.
-
-12.2 Effect of Termination. Upon termination, You agree to immediately
-stop any further use, reproduction, modification, sublicensing and
-distribution of the Covered Code. All sublicenses to the Covered Code
-which have been properly granted prior to termination shall survive
-any termination of this License. Provisions which, by their nature,
-should remain in effect beyond the termination of this License shall
-survive, including but not limited to Sections 3, 5, 8, 9, 10, 11,
-12.2 and 13. No party will be liable to any other for compensation,
-indemnity or damages of any sort solely as a result of terminating
-this License in accordance with its terms, and termination of this
-License will be without prejudice to any other right or remedy of
-any party.
-
-13. Miscellaneous.
-
-13.1 Government End Users. The Covered Code is a "commercial item" as
-defined in FAR 2.101. Government software and technical data rights in
-the Covered Code include only those rights customarily provided to the
-public as defined in this License. This customary commercial license
-in technical data and software is provided in accordance with FAR
-12.211 (Technical Data) and 12.212 (Computer Software) and, for
+days of becoming aware of such breach; (b) immediately in the event of
+the circumstances described in Section 13.5(b); or (c) automatically
+without notice from Apple if You, at any time during the term of this
+License, commence an action for patent infringement against Apple.
+
+12.2 Effect of Termination. Upon termination, You agree to
+immediately stop any further use, reproduction, modification,
+sublicensing and distribution of the Covered Code and to destroy all
+copies of the Covered Code that are in your possession or control.
+All sublicenses to the Covered Code which have been properly granted
+prior to termination shall survive any termination of this License.
+Provisions which, by their nature, should remain in effect beyond the
+termination of this License shall survive, including but not limited
+to Sections 3, 5, 8, 9, 10, 11, 12.2 and 13. Neither party will be
+liable to the other for compensation, indemnity or damages of any sort
+solely as a result of terminating this License in accordance with its
+terms, and termination of this License will be without prejudice to
+any other right or remedy of either party.
+
+13. Miscellaneous.
+
+13.1 Government End Users. The Covered Code is a "commercial item" as
+defined in FAR 2.101. Government software and technical data rights
+in the Covered Code include only those rights customarily provided to
+the public as defined in this License. This customary commercial
+license in technical data and software is provided in accordance with
+FAR 12.211 (Technical Data) and 12.212 (Computer Software) and, for
Department of Defense purchases, DFAR 252.227-7015 (Technical Data --
Commercial Items) and 227.7202-3 (Rights in Commercial Computer
-Software or Computer Software Documentation). Accordingly, all U.S.
+Software or Computer Software Documentation). Accordingly, all U.S.
Government End Users acquire Covered Code with only those rights set
forth herein.
-13.2 Relationship of Parties. This License will not be construed as
+13.2 Relationship of Parties. This License will not be construed as
creating an agency, partnership, joint venture or any other form of
-legal association between or among You, Apple or any Contributor, and
-You will not represent to the contrary, whether expressly, by
-implication, appearance or otherwise.
+legal association between You and Apple, and You will not represent to
+the contrary, whether expressly, by implication, appearance or
+otherwise.
-13.3 Independent Development. Nothing in this License will impair
+13.3 Independent Development. Nothing in this License will impair
Apple's right to acquire, license, develop, have others develop for
it, market and/or distribute technology or products that perform the
same or similar functions as, or otherwise compete with,
Modifications, Larger Works, technology or products that You may
develop, produce, market or distribute.
-13.4 Waiver; Construction. Failure by Apple or any Contributor to
-enforce any provision of this License will not be deemed a waiver of
-future enforcement of that or any other provision. Any law or
-regulation which provides that the language of a contract shall be
-construed against the drafter will not apply to this License.
+13.4 Waiver; Construction. Failure by Apple to enforce any provision
+of this License will not be deemed a waiver of future enforcement of
+that or any other provision. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+will not apply to this License.
-13.5 Severability. (a) If for any reason a court of competent
+13.5 Severability. (a) If for any reason a court of competent
jurisdiction finds any provision of this License, or portion thereof,
to be unenforceable, that provision of the License will be enforced to
the maximum extent permissible so as to effect the economic benefits
and intent of the parties, and the remainder of this License will
-continue in full force and effect. (b) Notwithstanding the foregoing,
+continue in full force and effect. (b) Notwithstanding the foregoing,
if applicable law prohibits or restricts You from fully and/or
specifically complying with Sections 2 and/or 3 or prevents the
enforceability of either of those Sections, this License will
the Covered Code and destroy all copies of it that are in your
possession or control.
-13.6 Dispute Resolution. Any litigation or other dispute resolution
+13.6 Dispute Resolution. Any litigation or other dispute resolution
between You and Apple relating to this License shall take place in the
Northern District of California, and You and Apple hereby consent to
the personal jurisdiction of, and venue in, the state and federal
application of the United Nations Convention on Contracts for the
International Sale of Goods is expressly excluded.
-13.7 Entire Agreement; Governing Law. This License constitutes the
+13.7 Entire Agreement; Governing Law. This License constitutes the
entire agreement between the parties with respect to the subject
-matter hereof. This License shall be governed by the laws of the
+matter hereof. This License shall be governed by the laws of the
United States and the State of California, except that body of
California law concerning conflicts of law.
EXHIBIT A.
-"Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
-Reserved.
-
-This file contains Original Code and/or Modifications of Original Code
-as defined in and that are subject to the Apple Public Source License
-Version 2.0 (the 'License'). You may not use this file except in
-compliance with the License. Please obtain a copy of the License at
-http://www.opensource.apple.com/apsl/ and read it before using this
-file.
+"Portions Copyright (c) 1999-2000 Apple Computer, Inc. All Rights
+Reserved. This file contains Original Code and/or Modifications of
+Original Code as defined in and that are subject to the Apple Public
+Source License Version 1.1 (the "License"). You may not use this file
+except in compliance with the License. Please obtain a copy of the
+License at http://www.apple.com/publicsource and read it before using
+this file.
The Original Code and all software distributed under the License are
-distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
-Please see the License for the specific language governing rights and
-limitations under the License."
+FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+License for the specific language governing rights and limitations
+under the License."
#include "CSPDLPlugin.h"
#include "SSKey.h"
+
+#ifndef SECURITYSERVER_ACL_EDITS
+
+#include <Security/aclclient.h>
+#include <Security/Access.h>
+#include <Security/TrustedApplication.h>
+
+//
+// ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer
+//
+class ClientSessionKey: public CssmClient::AclBearer
+{
+public:
+ ClientSessionKey(SecurityServer::ClientSession &clientSession, SecurityServer::KeyHandle keyHandle);
+ ~ClientSessionKey();
+
+ // Acl manipulation
+ virtual void getAcl(AutoAclEntryInfoList &aclInfos,
+ const char *selectionTag = NULL) const;
+ virtual void changeAcl(const CSSM_ACL_EDIT &aclEdit,
+ const CSSM_ACCESS_CREDENTIALS *cred = NULL);
+
+ // Acl owner manipulation
+ virtual void getOwner(AutoAclOwnerPrototype &owner) const;
+ virtual void changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner,
+ const CSSM_ACCESS_CREDENTIALS *cred = NULL);
+
+
+private:
+ SecurityServer::ClientSession &mClientSession;
+ SecurityServer::KeyHandle mKeyHandle;
+};
+
+#endif //!SECURITYSERVER_ACL_EDITS
+
+
using namespace SecurityServer;
//
#endif
return theKey;
}
+
+// Notification we receive when the acl on a key has changed. We should write it back to disk if it's persistant.
+void
+SSCSPDLSession::didChangeKeyAcl(SecurityServer::ClientSession &clientSession,
+ KeyHandle keyHandle, CSSM_ACL_AUTHORIZATION_TAG tag)
+{
+#ifndef SECURITYSERVER_ACL_EDITS
+ {
+ // The user checked to don't ask again checkbox in the rogue app alert. Let's edit the ACL for this key and add the calling application (ourself) to it.
+ secdebug("keyacl", "SSCSPDLSession::didChangeKeyAcl(keyHandle: %lu tag: %lu)", keyHandle, tag);
+ ClientSessionKey csKey(clientSession, keyHandle); // the underlying key
+ KeychainCore::SecPointer<KeychainCore::Access> access = new KeychainCore::Access(csKey); // extract access rights
+ KeychainCore::SecPointer<KeychainCore::TrustedApplication> thisApp = new KeychainCore::TrustedApplication;
+ access->addApplicationToRight(tag, thisApp.get()); // add this app
+ access->setAccess(csKey, true); // commit
+ }
+#endif // !SECURITYSERVER_ACL_EDITS
+
+ SSKey *theKey = NULL;
+
+ {
+ // Lookup the SSKey for the KeyHandle
+ StLock<Mutex> _(mKeyMapLock);
+ KeyMap::const_iterator it;
+ KeyMap::const_iterator end = mKeyMap.end();
+ for (it = mKeyMap.begin(); it != end; ++it)
+ {
+ SSKey *aKey = dynamic_cast<SSKey *>(it->second);
+ if (aKey->optionalKeyHandle() == keyHandle)
+ {
+ // Write the key to disk if it's persistant.
+ theKey = aKey;
+ break;
+ }
+ }
+ }
+
+ if (theKey)
+ {
+ theKey->didChangeAcl();
+ }
+ else
+ {
+ // @@@ Should we really throw here or just continue without updating the ACL? In reality this should never happen, so let's at least log it and throw.
+ secdebug("keyacl", "SSCSPDLSession::didChangeKeyAcl() keyHandle: %lu not found in map", keyHandle);
+ CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE);
+ }
+}
+
+void
+SSCSPDLSession::didChangeKeyAclCallback(void *context, SecurityServer::ClientSession &clientSession,
+ SecurityServer::KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag)
+{
+ reinterpret_cast<SSCSPDLSession *>(context)->didChangeKeyAcl(clientSession, key, tag);
+}
+
+#ifndef SECURITYSERVER_ACL_EDITS
+//
+// ClientSessionKey - Lightweight wrapper for a KeyHandle that is also an CssmClient::AclBearer
+//
+ClientSessionKey::ClientSessionKey(ClientSession &clientSession, SecurityServer::KeyHandle keyHandle) :
+ mClientSession(clientSession),
+ mKeyHandle(keyHandle)
+{
+}
+
+ClientSessionKey::~ClientSessionKey()
+{
+}
+
+void
+ClientSessionKey::getAcl(AutoAclEntryInfoList &aclInfos,
+ const char *selectionTag) const
+{
+ secdebug("keyacl", "ClientSessionKey::getAcl() keyHandle: %lu", mKeyHandle);
+ aclInfos.allocator(mClientSession.returnAllocator);
+ mClientSession.getKeyAcl(mKeyHandle, selectionTag,
+ *static_cast<uint32 *>(aclInfos),
+ *reinterpret_cast<AclEntryInfo **>(static_cast<CSSM_ACL_ENTRY_INFO_PTR *>(aclInfos)));
+}
+
+void
+ClientSessionKey::changeAcl(const CSSM_ACL_EDIT &aclEdit,
+ const CSSM_ACCESS_CREDENTIALS *cred)
+{
+ secdebug("keyacl", "ClientSessionKey::changeAcl() keyHandle: %lu", mKeyHandle);
+ mClientSession.changeKeyAcl(mKeyHandle, AccessCredentials::overlay(*cred), AclEdit::overlay(aclEdit));
+}
+
+void
+ClientSessionKey::getOwner(AutoAclOwnerPrototype &owner) const
+{
+ secdebug("keyacl", "ClientSessionKey::getOwner() keyHandle: %lu", mKeyHandle);
+ owner.allocator(mClientSession.returnAllocator);
+ mClientSession.getKeyOwner(mKeyHandle,
+ *reinterpret_cast<AclOwnerPrototype *>(static_cast<CSSM_ACL_OWNER_PROTOTYPE *>(owner)));
+}
+
+void
+ClientSessionKey::changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner,
+ const CSSM_ACCESS_CREDENTIALS *cred)
+{
+ secdebug("keyacl", "ClientSessionKey::changeOwner() keyHandle: %lu", mKeyHandle);
+ mClientSession.changeKeyOwner(mKeyHandle, AccessCredentials::overlay(*cred), AclOwnerPrototype::overlay(newOwner));
+}
+
+#endif // !SECURITYSERVER_ACL_EDITS
CssmKey &outKey, SSDatabase &inSSDatabase,
uint32 inKeyAttr, const CssmData *inKeyLabel);
SSKey &lookupKey(const CssmKey &inKey);
+
+ /* Notification we receive when a key's acl has been modified. */
+ void didChangeKeyAcl(SecurityServer::ClientSession &clientSession,
+ SecurityServer::KeyHandle keyHandle, CSSM_ACL_AUTHORIZATION_TAG tag);
+
+ static void didChangeKeyAclCallback(void *context, SecurityServer::ClientSession &clientSession,
+ SecurityServer::KeyHandle keyHandle, CSSM_ACL_AUTHORIZATION_TAG tag);
};
mRawCsp(rawCsp),
mClientSession(CssmAllocator::standard(), *this)
{
+ mClientSession.registerForAclEdits(SSCSPDLSession::didChangeKeyAclCallback, &mSSCSPDLSession);
}
//
}
/* There may be more, but we'll leave it to SS and CSP to decide */
}
-
void validateKeyAttr(uint32 reqKeyAttr);
SecurityServer::ClientSession mClientSession;
-
};
mDL(Module(gGuidAppleFileDL, Cssm::standard())),
mClientSession(CssmAllocator::standard(), static_cast<PluginSession &>(*this))
{
+ mClientSession.registerForAclEdits(SSCSPDLSession::didChangeKeyAclCallback, &mSSCSPDLSession);
// @@@ mDL.allocator(*static_cast<DatabaseSession *>(this));
mDL->allocator(allocator());
mDL->version(version);
return mClientSession;
}
+KeyHandle SSKey::optionalKeyHandle() const
+{
+ return mKeyHandle;
+}
+
KeyHandle
SSKey::keyHandle()
{
const AclOwnerPrototype &newOwner)
{
clientSession().changeKeyOwner(keyHandle(), accessCred, newOwner);
- if (mUniqueId == true)
- {
- // The key is persistant, make the change on disk.
- CssmDataContainer keyBlob(mAllocator);
- clientSession().encodeKey(keyHandle(), keyBlob);
- mUniqueId->modify(mRecordType, NULL, &keyBlob,
- CSSM_DB_MODIFY_ATTRIBUTE_NONE);
- }
+ didChangeAcl();
}
void
SSKey::changeAcl(const AccessCredentials &accessCred, const AclEdit &aclEdit)
{
clientSession().changeKeyAcl(keyHandle(), accessCred, aclEdit);
+ didChangeAcl();
+}
+
+void
+SSKey::didChangeAcl()
+{
if (mUniqueId == true)
{
+ secdebug("keyacl", "SSKey::didChangeAcl() keyHandle: %lu updating DL entry", mKeyHandle);
// The key is persistant, make the change on disk.
CssmDataContainer keyBlob(mAllocator);
clientSession().encodeKey(keyHandle(), keyBlob);
- mUniqueId->modify(mRecordType, NULL, &keyBlob,
- CSSM_DB_MODIFY_ATTRIBUTE_NONE);
+ mUniqueId->modify(mRecordType, NULL, &keyBlob, CSSM_DB_MODIFY_ATTRIBUTE_NONE);
+ }
+ else
+ {
+ secdebug("keyacl", "SSKey::didChangeAcl() keyHandle: %lu transient key no update done", mKeyHandle);
}
}
CSSM_BOOL deleteKey);
SecurityServer::ClientSession &clientSession();
+
+ /* Might return SecurityServer::noKey if the key has not yet been instantiated. */
+ SecurityServer::KeyHandle optionalKeyHandle() const;
+
+ /* Will instantiate the key if needed. */
SecurityServer::KeyHandle keyHandle();
// ACL retrieval and change operations
void changeAcl(const AccessCredentials &accessCred,
const AclEdit &aclEdit);
+ // Reencode and write to disk if we are a persistant key.
+ void didChangeAcl();
+
private:
CssmAllocator &mAllocator;
SecurityServer::KeyHandle mKeyHandle;
policyFail = CSSM_TRUE;
thisTpCertInfo->addStatusCode(CSSMERR_APPLETP_INVALID_KEY_USAGE);
}
-
+ #if 0
if((policy == kTP_SMIME) && !thisCertInfo->keyUsage.critical) {
/*
* Per Radar 3410245, allow this for intermediate certs.
thisTpCertInfo->addStatusCode(CSSMERR_APPLETP_SMIME_KEYUSAGE_NOT_CRITICAL);
}
}
-
+ #endif
}
else if(policy == kTPiSign) {
/*
#pragma mark ÑÑÑÑ Constructor/Destructor ÑÑÑÑ
Globals::Globals() :
+apiLock(Mutex::recursive),
mUI(true)
{
}
#include <Security/SecCFTypes.h>
#include <Security/SecRuntime.h>
+#include <Security/threading.h>
+#include <Security/Globals.h>
namespace Security
{
void
CFClass::finalizeType(CFTypeRef cf)
{
+ /*
+ * Called on a CFRelease of any Sec object: single thread through
+ * same lock held by public API calls. This is a recursive lock
+ * so it's safe to do this for CF objects allocated and released
+ * within the Sec layer.
+ */
+ StLock<Mutex> _(globals().apiLock);
SecCFObject *obj = SecCFObject::optional(cf);
if (!obj->isNew())
obj->~SecCFObject();
#include <Security/Security.h>
#include <Security/SecTrustPriv.h>
#include <Security/SecPolicyPriv.h>
+#include <Security/SecKeyPriv.h>
/* X.509 includes, from cssmapi */
#include <Security/x509defs.h> /* x.509 function and type defs */
return crtn;
}
+/* Get CSP, key in CSSM format from a SecKeyRef */
+static OSStatus sslGetKeyParts(
+ SecKeyRef keyRef,
+ const CSSM_KEY **cssmKey,
+ CSSM_CSP_HANDLE *cspHand)
+{
+ OSStatus ortn = SecKeyGetCSSMKey(keyRef, cssmKey);
+ if(ortn) {
+ sslErrorLog("sslGetKeyParts: SecKeyGetCSSMKey err %d\n",
+ (int)ortn);
+ return ortn;
+ }
+ ortn = SecKeyGetCSPHandle(keyRef, cspHand);
+ if(ortn) {
+ sslErrorLog("sslGetKeyParts: SecKeyGetCSPHandle err %d\n",
+ (int)ortn);
+ }
+ return ortn;
+}
+
#pragma mark -
#pragma mark *** CSSM_DATA routines ***
*/
OSStatus sslRawSign(
SSLContext *ctx,
- const CSSM_KEY *privKey,
- CSSM_CSP_HANDLE cspHand,
+ SecKeyRef privKeyRef,
const UInt8 *plainText,
UInt32 plainTextLen,
UInt8 *sig, // mallocd by caller; RETURNED
OSStatus serr;
CSSM_DATA sigData;
CSSM_DATA ptextData;
+ CSSM_CSP_HANDLE cspHand;
+ const CSSM_KEY *privKey;
+ const CSSM_ACCESS_CREDENTIALS *creds;
assert(ctx != NULL);
- if((privKey == NULL) ||
- (cspHand == 0) ||
+ if((privKeyRef == NULL) ||
(plainText == NULL) ||
(sig == NULL) ||
(actualBytes == NULL)) {
}
*actualBytes = 0;
+ /* Get CSP, signing key in CSSM format */
+ serr = sslGetKeyParts(privKeyRef, &privKey, &cspHand);
+ if(serr) {
+ return serr;
+ }
+ assert(privKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PRIVATE_KEY);
+
CSSM_ALGORITHMS sigAlg;
serr = sslKeyToSigAlg(privKey, sigAlg);
if(serr) {
return serr;
}
+
+ /*
+ * Get default creds
+ * FIXME: per 3420180, this needs to allow app-specified creds via
+ * an new API
+ */
+ serr = SecKeyGetCredentials(privKeyRef,
+ CSSM_ACL_AUTHORIZATION_SIGN,
+ kSecCredentialTypeDefault,
+ &creds);
+ if(serr) {
+ sslErrorLog("sslRawSign: SecKeyGetCredentials err %lu\n", serr);
+ return serr;
+ }
+
crtn = CSSM_CSP_CreateSignatureContext(cspHand,
sigAlg,
- NULL, // passPhrase
+ creds,
privKey,
&sigHand);
if(crtn) {
OSStatus sslRsaDecrypt(
SSLContext *ctx,
- const CSSM_KEY *privKey,
- CSSM_CSP_HANDLE cspHand,
+ SecKeyRef privKeyRef,
const UInt8 *cipherText,
UInt32 cipherTextLen,
UInt8 *plainText, // mallocd by caller; RETURNED
OSStatus serr = errSSLInternal;
CSSM_RETURN crtn;
uint32 bytesMoved = 0;
- CSSM_ACCESS_CREDENTIALS creds;
+ CSSM_CSP_HANDLE cspHand;
+ const CSSM_KEY *privKey;
+ const CSSM_ACCESS_CREDENTIALS *creds;
assert(ctx != NULL);
assert(actualBytes != NULL);
*actualBytes = 0;
- if((privKey == NULL) || (cspHand == 0)) {
- sslErrorLog("sslRsaDecrypt: bad privKey/cspHand\n");
+ if(privKeyRef == NULL) {
+ sslErrorLog("sslRsaDecrypt: bad privKey\n");
return errSSLInternal;
}
+
+ /* Get CSP, signing key in CSSM format */
+ serr = sslGetKeyParts(privKeyRef, &privKey, &cspHand);
+ if(serr) {
+ return serr;
+ }
assert(privKey->KeyHeader.KeyClass == CSSM_KEYCLASS_PRIVATE_KEY);
- memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
+
+ /*
+ * Get default creds
+ * FIXME: per 3420180, this needs to allow app-specified creds via
+ * an new API
+ */
+ serr = SecKeyGetCredentials(privKeyRef,
+ CSSM_ACL_AUTHORIZATION_DECRYPT,
+ kSecCredentialTypeDefault,
+ &creds);
+ if(serr) {
+ sslErrorLog("sslRsaDecrypt: SecKeyGetCredentials err %lu\n", serr);
+ return serr;
+ }
crtn = CSSM_CSP_CreateAsymmetricContext(cspHand,
CSSM_ALGID_RSA,
- &creds,
+ creds,
privKey,
CSSM_PADDING_PKCS1,
&cryptHand);
CSSM_KEY wrappedKey;
CSSM_BOOL didWrap = CSSM_FALSE;
const CSSM_KEYHEADER *hdr;
- CSSM_CC_HANDLE ccHand;
- CSSM_RETURN crtn;
SSLBuffer pubKeyBlob;
- OSStatus srtn;
- CSSM_ACCESS_CREDENTIALS creds;
+ OSStatus srtn;
assert(ctx != NULL);
assert(modulus != NULL);
sslErrorLog("sslGetPubKeyBits: bad AlgorithmId (%ld)\n", hdr->AlgorithmId);
return errSSLInternal;
}
-
+
+ /* Note currently ALL public keys are raw, obtained from the CL... */
+ assert(hdr->BlobType == CSSM_KEYBLOB_RAW);
+
/*
* Handle possible reference format - I think it should be in
* blob form since it came from the DL, but conversion is
break;
case CSSM_KEYBLOB_REFERENCE:
+
+ sslErrorLog("sslGetPubKeyBits: bad BlobType (%ld)\n",
+ hdr->BlobType);
+ return errSSLInternal;
+
+ #if 0
/*
* Convert to a blob via "NULL wrap"; no wrapping key,
* ALGID_NONE
didWrap = CSSM_TRUE;
CSSM_TO_SSLBUF(&wrappedKey.KeyData, &pubKeyBlob);
break;
-
+ #endif /* 0 */
+
default:
sslErrorLog("sslGetPubKeyBits: bad BlobType (%ld)\n",
hdr->BlobType);
}
/* private signing key required */
- if(ctx->signingPrivKey == NULL) {
+ if(ctx->signingPrivKeyRef == NULL) {
sslErrorLog("sslVerifyNegotiatedCipher: no signing key\n");
return errSSLBadConfiguration;
}
- if(ctx->signingPrivKey->KeyHeader.AlgorithmId != requireAlg) {
- sslErrorLog("sslVerifyNegotiatedCipher: signing key alg mismatch\n");
- return errSSLBadConfiguration;
+ {
+ const CSSM_KEY *cssmKey;
+ OSStatus ortn = SecKeyGetCSSMKey(ctx->signingPrivKeyRef, &cssmKey);
+ if(ortn) {
+ sslErrorLog("sslVerifyNegotiatedCipher: SecKeyGetCSSMKey err %d\n",
+ (int)ortn);
+ return ortn;
+ }
+ if(cssmKey->KeyHeader.AlgorithmId != requireAlg) {
+ sslErrorLog("sslVerifyNegotiatedCipher: signing key alg mismatch\n");
+ return errSSLBadConfiguration;
+ }
}
return noErr;
}
*/
OSStatus sslRawSign(
SSLContext *ctx,
- const CSSM_KEY *privKey,
- CSSM_CSP_HANDLE cspHand,
+ SecKeyRef privKeyRef,
const UInt8 *plainText,
UInt32 plainTextLen,
UInt8 *sig, // mallocd by caller; RETURNED
UInt32 *actualBytes); // RETURNED
OSStatus sslRsaDecrypt(
SSLContext *ctx,
- const CSSM_KEY *privKey,
- CSSM_CSP_HANDLE cspHand,
+ SecKeyRef privKeyRef,
const UInt8 *cipherText,
UInt32 cipherTextLen,
UInt8 *plainText, // mallocd by caller; RETURNED
/* crypto state in CDSA-centric terms */
- CSSM_KEY_PTR signingPrivKey; /* our private signing key */
- CSSM_KEY_PTR signingPubKey; /* our public signing key */
- CSSM_CSP_HANDLE signingKeyCsp; /* associated DL/CSP */
+ SecKeyRef signingPrivKeyRef; /* our private signing key */
+ CSSM_KEY_PTR signingPubKey; /* our public signing key */
- CSSM_KEY_PTR encryptPrivKey; /* our private encrypt key, for
+ SecKeyRef encryptPrivKeyRef; /* our private encrypt key, for
* server-initiated key exchange */
CSSM_KEY_PTR encryptPubKey; /* public version of above */
- CSSM_CSP_HANDLE encryptKeyCsp;
CSSM_KEY_PTR peerPubKey;
CSSM_CSP_HANDLE peerPubKeyCsp; /* may not be needed, we figure this
CFArrayRef certs,
SSLCertificate **destCert, /* &ctx->{localCert,encryptCert} */
CSSM_KEY_PTR *pubKey, /* &ctx->signingPubKey, etc. */
- CSSM_KEY_PTR *privKey, /* &ctx->signingPrivKey, etc. */
- CSSM_CSP_HANDLE *cspHand); /* &ctx->signingKeyCsp, etc. */
+ SecKeyRef *privKeyRef); /* &ctx->signingPrivKeyRef, etc. */
#ifdef __cplusplus
}
unsigned clearLength, encryptedLength, keyArgLength;
UInt32 secretLength, localKeyModulusLen;
UInt8 *charPtr;
- const CSSM_KEY *decryptKey;
- CSSM_CSP_HANDLE decryptCspHand;
+ const CSSM_KEY *cssmKey;
+ SecKeyRef decryptKeyRef = NULL;
if (msg.length < 9) {
sslErrorLog("SSL2ProcessClientMasterKey: msg.length error 1\n");
* Just as in SSL2EncodeServerHello, which key we use depends on the
* app's config.
*/
- if(ctx->encryptPrivKey) {
- decryptKey = ctx->encryptPrivKey;
- assert(ctx->encryptKeyCsp != 0);
- decryptCspHand = ctx->encryptKeyCsp;
+ if(ctx->encryptPrivKeyRef) {
+ decryptKeyRef = ctx->encryptPrivKeyRef;
+ /* FIXME: when 3420180 is implemented, pick appropriate creds here */
}
- else if(ctx->signingPrivKey) {
- decryptKey = ctx->signingPrivKey;
- assert(ctx->signingKeyCsp != 0);
- decryptCspHand = ctx->signingKeyCsp;
+ else if(ctx->signingPrivKeyRef) {
+ decryptKeyRef = ctx->signingPrivKeyRef;
+ /* FIXME: when 3420180 is implemented, pick appropriate creds here */
}
else {
/* app configuration error */
sslErrorLog("SSL2ProcessClientMasterKey: No server key!\n");
return errSSLBadConfiguration;
}
- localKeyModulusLen = sslKeyLengthInBytes(decryptKey);
+ err = SecKeyGetCSSMKey(decryptKeyRef, &cssmKey);
+ if(err) {
+ sslErrorLog("SSL2ProcessClientMasterKey: SecKeyGetCSSMKey err %d\n", (int)err);
+ return err;
+ }
+ localKeyModulusLen = sslKeyLengthInBytes(cssmKey);
if (encryptedLength != localKeyModulusLen) {
sslErrorLog("SSL2ProcessClientMasterKey: encryptedLength error 1\n");
return err;
err = sslRsaDecrypt(ctx,
- decryptKey,
- decryptCspHand,
+ decryptKeyRef,
charPtr,
encryptedLength,
secretData.data,
SSLBuffer hashDataBuf, shaMsgState, md5MsgState;
UInt32 len;
UInt32 outputLen;
-
+ const CSSM_KEY *cssmKey;
+
certVerify.contents.data = 0;
hashDataBuf.data = hashData;
hashDataBuf.length = 36;
shaMsgState, md5MsgState)) != 0)
goto fail;
- assert(ctx->signingPrivKey != NULL);
- len = sslKeyLengthInBytes(ctx->signingPrivKey);
+ assert(ctx->signingPrivKeyRef != NULL);
+ err = SecKeyGetCSSMKey(ctx->signingPrivKeyRef, &cssmKey);
+ if(err) {
+ sslErrorLog("SSLEncodeCertificateVerify: SecKeyGetCSSMKey err %d\n", (int)err);
+ return err;
+ }
+ len = sslKeyLengthInBytes(cssmKey);
certVerify.contentType = SSL_RecordTypeHandshake;
assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
SSLEncodeInt(certVerify.contents.data+4, len, 2);
err = sslRawSign(ctx,
- ctx->signingPrivKey,
- ctx->signingKeyCsp,
+ ctx->signingPrivKeyRef,
hashData, // data to sign
36, // MD5 size + SHA1 size
certVerify.contents.data+6, // signature destination
* are all raw keys, and all Apple CSPs dispose of raw keys in the same
* way.
*/
- sslFreeKey(ctx->signingKeyCsp, &ctx->signingPubKey, NULL);
- sslFreeKey(ctx->encryptKeyCsp, &ctx->encryptPubKey, NULL);
+ sslFreeKey(ctx->cspHand, &ctx->signingPubKey, NULL);
+ sslFreeKey(ctx->cspHand, &ctx->encryptPubKey, NULL);
sslFreeKey(ctx->peerPubKeyCsp, &ctx->peerPubKey, NULL);
+ if(ctx->signingPrivKeyRef) {
+ CFRelease(ctx->signingPrivKeyRef);
+ }
+ if(ctx->encryptPrivKeyRef) {
+ CFRelease(ctx->encryptPrivKeyRef);
+ }
sslFreeTrustedRoots(ctx);
detachFromAll(ctx);
certRefs,
&ctx->localCert,
&ctx->signingPubKey,
- &ctx->signingPrivKey,
- &ctx->signingKeyCsp
- #if ST_KC_KEYS_NEED_REF
- ,
- &ctx->signingKeyRef
- #else
- );
- #endif
+ &ctx->signingPrivKeyRef);
}
OSStatus
certRefs,
&ctx->encryptCert,
&ctx->encryptPubKey,
- &ctx->encryptPrivKey,
- &ctx->encryptKeyCsp);
+ &ctx->encryptPrivKeyRef);
}
OSStatus
/* the "proper" way - app decides. */
case SSL_RSA:
#endif
- if(ctx->encryptPrivKey != NULL) {
+ if(ctx->encryptPrivKeyRef != NULL) {
doServerKeyExch = true;
}
break;
{ OSStatus err;
SSLBuffer modulus, exponent;
UInt8 *charPtr;
-
+
+ if(err = attachToCsp(ctx)) {
+ return err;
+ }
+
+ /* Note currently ALL public keys are raw, obtained from the CL... */
+ assert((*key)->KeyHeader.BlobType == CSSM_KEYBLOB_RAW);
err = sslGetPubKeyBits(ctx,
*key,
- ctx->encryptKeyCsp,
+ ctx->cspHand,
&modulus,
&exponent);
if(err) {
UInt32 maxSigLen;
UInt32 actSigLen;
SSLBuffer signature;
+ const CSSM_KEY *cssmKey;
assert(ctx->protocolSide == SSL_ServerSide);
assert(ctx->signingPubKey != NULL);
goto fail;
/* preallocate a buffer for signing */
- err = sslGetMaxSigSize(ctx->signingPrivKey, maxSigLen);
+ err = SecKeyGetCSSMKey(ctx->signingPrivKeyRef, &cssmKey);
+ if(err) {
+ sslErrorLog("SSLEncodeSignedServerKeyExchange: SecKeyGetCSSMKey err %d\n",
+ (int)err);
+ goto fail;
+ }
+ err = sslGetMaxSigSize(cssmKey, maxSigLen);
if(err) {
goto fail;
}
}
err = sslRawSign(ctx,
- ctx->signingPrivKey,
- ctx->signingKeyCsp,
+ ctx->signingPrivKeyRef,
dataToSign, // one or two hashes
dataToSignLen,
signature.data,
SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
{ OSStatus err;
UInt32 outputLen, localKeyModulusLen;
- CSSM_KEY_PTR *key;
SSLProtocolVersion version;
Boolean useEncryptKey = false;
UInt8 *src = NULL;
-
-
- /* different key names, also need CSP handle */
- CSSM_CSP_HANDLE cspHand;
-
+ SecKeyRef keyRef = NULL;
+ const CSSM_KEY *cssmKey;
+
assert(ctx->protocolSide == SSL_ServerSide);
#if SSL_SERVER_KEYEXCH_HACK
#else /* !SSL_SERVER_KEYEXCH_HACK */
/* The "correct" way, I think, which doesn't work with Netscape */
- if (ctx->encryptPrivKey) {
+ if (ctx->encryptPrivKeyRef) {
useEncryptKey = true;
}
#endif /* SSL_SERVER_KEYEXCH_HACK */
if (useEncryptKey) {
- key = &ctx->encryptPrivKey;
- cspHand = ctx->encryptKeyCsp;
+ keyRef = ctx->encryptPrivKeyRef;
+ /* FIXME: when 3420180 is implemented, pick appropriate creds here */
}
else {
- key = &ctx->signingPrivKey;
- cspHand = ctx->signingKeyCsp;
+ keyRef = ctx->signingPrivKeyRef;
+ /* FIXME: when 3420180 is implemented, pick appropriate creds here */
+ }
+ err = SecKeyGetCSSMKey(keyRef, &cssmKey);
+ if(err) {
+ sslErrorLog("SSLDecodeRSAKeyExchange: SecKeyGetCSSMKey err %d\n",
+ (int)err);
+ return err;
}
- localKeyModulusLen = sslKeyLengthInBytes(*key);
+ localKeyModulusLen = sslKeyLengthInBytes(cssmKey);
/*
* We have to tolerate incoming key exchange msgs with and without the
* See http://eprint.iacr.org/2003/052/ for more info.
*/
err = sslRsaDecrypt(ctx,
- *key,
- cspHand,
+ keyRef,
src,
localKeyModulusLen, // ciphertext len
ctx->preMasterSecret.data,
CFArrayRef certs,
SSLCertificate **destCert, /* &ctx->{localCert,encryptCert} */
CSSM_KEY_PTR *pubKey, /* &ctx->signingPubKey, etc. */
- CSSM_KEY_PTR *privKey, /* &ctx->signingPrivKey, etc. */
- CSSM_CSP_HANDLE *cspHand) /* &ctx->signingKeyCsp, etc. */
+ SecKeyRef *privKeyRef) /* &ctx->signingPrivKeyRef, etc. */
{
CFIndex numCerts;
CFIndex cert;
SSLCertificate *certChain = NULL;
SSLCertificate *thisSslCert;
- SecKeychainRef kcRef;
OSStatus ortn;
SecIdentityRef identity;
SecCertificateRef certRef;
assert(ctx != NULL);
assert(destCert != NULL); /* though its referent may be NULL */
assert(pubKey != NULL);
- assert(privKey != NULL);
- assert(cspHand != NULL);
+ assert(privKeyRef != NULL);
sslDeleteCertificateChain(*destCert, ctx);
*destCert = NULL;
*pubKey = NULL;
- *privKey = NULL;
- *cspHand = 0;
+ *privKeyRef = NULL;
if(certs == NULL) {
sslErrorLog("parseIncomingCerts: NULL incoming cert array\n");
/*
* Certs[0] is an SecIdentityRef from which we extract subject cert,
- * privKey, pubKey, and cspHand.
+ * privKeyRef, pubKey.
*
* 1. ensure the first element is a SecIdentityRef.
*/
}
/*
- * 2. Extract cert, keys, CSP handle and convert to local format.
+ * 2. Extract cert, keys and convert to local format.
*/
ortn = SecIdentityCopyCertificate(identity, &certRef);
if(ortn) {
(int)ortn);
return ortn;
}
- ortn = SecKeyGetCSSMKey(keyRef, (const CSSM_KEY **)privKey);
- if(ortn) {
- sslErrorLog("parseIncomingCerts: SecKeyGetCSSMKey err %d\n",
- (int)ortn);
- return ortn;
- }
- /* FIXME = release keyRef? */
+ *privKeyRef = keyRef;
/* obtain public key from cert */
ortn = SecCertificateGetCLHandle(certRef, &clHand);
return (OSStatus)crtn;
}
- /* obtain keychain from key, CSP handle from keychain */
- ortn = SecKeychainItemCopyKeychain((SecKeychainItemRef)keyRef, &kcRef);
- if(ortn) {
- sslErrorLog("parseIncomingCerts: SecKeychainItemCopyKeychain err %d\n",
- (int)ortn);
- return ortn;
- }
- ortn = SecKeychainGetCSPHandle(kcRef, cspHand);
- if(ortn) {
- sslErrorLog("parseIncomingCerts: SecKeychainGetCSPHandle err %d\n",
- (int)ortn);
- return ortn;
- }
-
/* OK, that's the subject cert. Fetch optional remaining certs. */
/*
* Convert: CFArray of SecCertificateRefs --> chain of SSLCertificates.
certChain = thisSslCert;
}
- /* validate the whole mess, skipping host name verify */
- ortn = sslVerifyCertChain(ctx, *certChain, false);
- if(ortn) {
- goto errOut;
- }
-
/* SUCCESS */
*destCert = certChain;
return noErr;
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 163;
+ DYLIB_CURRENT_VERSION = 164.1;
FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/BSafe.framework/Headers\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/BSafe.framework/Headers\" \"$(SRCROOT)/AppleCSP\" \"$(SRCROOT)/AppleCSP/open_ssl\"";
LIBRARY_STYLE = STATIC;
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 163;
+ DYLIB_CURRENT_VERSION = 164.1;
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "-DVDADER_RULES";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 163;
+ DYLIB_CURRENT_VERSION = 164.1;
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 163;
+ DYLIB_CURRENT_VERSION = 164.1;
FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 163;
+ DYLIB_CURRENT_VERSION = 164.1;
FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
01FA8900FFF2BC5611CD283A,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 163;
+ CURRENT_PROJECT_VERSION = 164.1;
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/derived_src\"";
INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)";
LIBRARY_SEARCH_PATHS = "";
01FA890AFFF2BCA811CD283A,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 163;
+ CURRENT_PROJECT_VERSION = 164.1;
INSTALL_PATH = "$(SYSTEM_CORE_SERVICES_DIR)";
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 163;
+ DYLIB_CURRENT_VERSION = 164.1;
INSTALL_PATH = /usr/local/lib;
LIBRARY_STYLE = STATIC;
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
F5DDE3AE00B3358F01CD283A,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 163;
+ CURRENT_PROJECT_VERSION = 164.1;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 163;
+ DYLIB_CURRENT_VERSION = 164.1;
FRAMEWORK_SEARCH_PATHS = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"";
FRAMEWORK_VERSION = A;
HEADER_SEARCH_PATHS = "\"$(SRCROOT)\" \"$(BUILT_PRODUCTS_DIR)/derived_src\"";
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
- <string>2.0</string>
+ <string>2.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>163</string>
+ <string>164.1</string>
</dict>
</plist>
";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 163;
+ DYLIB_CURRENT_VERSION = 164.1;
HEADER_SEARCH_PATHS = "\"$(BUILT_PRODUCTS_DIR)/include\"";
INSTALL_PATH = /usr/local/lib;
LIBRARY_STYLE = STATIC;
325EAA2800D6B08805CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 163;
+ CURRENT_PROJECT_VERSION = 164.1;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>2.0</string>
+ <string>2.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>163</string>
+ <string>164.1</string>
</dict>
</plist>
";
3290382100D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 163;
+ CURRENT_PROJECT_VERSION = 164.1;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>2.0</string>
+ <string>2.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>163</string>
+ <string>164.1</string>
</dict>
</plist>
";
3290382700D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 163;
+ CURRENT_PROJECT_VERSION = 164.1;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>2.0</string>
+ <string>2.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>163</string>
+ <string>164.1</string>
</dict>
</plist>
";
3290382D00D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 163;
+ CURRENT_PROJECT_VERSION = 164.1;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_CFLAGS = "";
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>2.0</string>
+ <string>2.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>163</string>
+ <string>164.1</string>
</dict>
</plist>
";
3290383300D6BA5905CD296C,
);
buildSettings = {
- CURRENT_PROJECT_VERSION = 163;
+ CURRENT_PROJECT_VERSION = 164.1;
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-Os -DNDEBUG";
OTHER_LDFLAGS = "-bundle -undefined error";
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
- <string>2.0</string>
+ <string>2.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>163</string>
+ <string>164.1</string>
</dict>
</plist>
";
);
buildSettings = {
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 163;
+ DYLIB_CURRENT_VERSION = 164.1;
INSTALL_PATH = /usr/local/lib;
LIBRARY_STYLE = STATIC;
OTHER_CFLAGS = "";
namespace Security {
namespace SecurityServer {
+//
+// Static callback stuff
+//
+ClientSession::DidChangeKeyAclCallback *ClientSession::mCallback = NULL;
+void *ClientSession::mCallbackContext = NULL;
//
// The process-global object
bool ClientSession::mSetupSession;
const char *ClientSession::mContactName;
-
//
// Construct a client session
//
{ }
+void
+ClientSession::registerForAclEdits(DidChangeKeyAclCallback *callback, void *context)
+{
+ mCallback = callback;
+ mCallbackContext = context;
+}
+
//
// Activate a client session: This connects to the SecurityServer and executes
// application authentication
}
+void ClientSession::addApplicationAclSubject(KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag)
+{
+ /* Notify our client if they are interested. */
+ if (mCallback && mCallbackContext)
+ {
+ secdebug("keyacl", "ClientSession::addApplicationAclSubject(keyHandle: %lu tag: %lu)", key, tag);
+ mCallback(mCallbackContext, *this, key, tag);
+ }
+ else
+ secdebug("keyacl", "ClientSession::addApplicationAclSubject() with NULL mCallback");
+}
+
+
} // end namespace SecurityServer
} // end namespace Security
class ClientSession {
NOCOPY(ClientSession)
public:
+ typedef void DidChangeKeyAclCallback(void *context, ClientSession &clientSession,
+ KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag);
+
ClientSession(CssmAllocator &standard, CssmAllocator &returning);
virtual ~ClientSession();
-
+
+ void registerForAclEdits(DidChangeKeyAclCallback *callback, void *context);
+
CssmAllocator &internalAllocator;
CssmAllocator &returnAllocator;
void changeOwner(AclKind kind, KeyHandle key, const AccessCredentials &cred,
const AclOwnerPrototype &edit);
+ void addApplicationAclSubject(KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag);
+
private:
+ static DidChangeKeyAclCallback *mCallback;
+ static void *mCallbackContext;
+
static UnixPlusPlus::StaticForkMonitor mHasForked; // global fork indicator
struct Thread {
{
SendContext ctx(context);
DataOutput sig(signature, alloc);
- IPC(ucsp_client_generateSignature(UCSP_ARGS, CONTEXT(ctx), key, signOnlyAlgorithm,
- DATA(data), DATA(sig)));
+ IPCKEY(ucsp_client_generateSignature(UCSP_ARGS, CONTEXT(ctx), key, signOnlyAlgorithm,
+ DATA(data), DATA(sig)),
+ key, CSSM_ACL_AUTHORIZATION_SIGN);
}
void ClientSession::verifySignature(const Context &context, KeyHandle key,
{
SendContext ctx(context);
DataOutput sig(signature, alloc);
- IPC(ucsp_client_generateMac(UCSP_ARGS, CONTEXT(ctx), key,
- DATA(data), DATA(sig)));
+ IPCKEY(ucsp_client_generateMac(UCSP_ARGS, CONTEXT(ctx), key,
+ DATA(data), DATA(sig)),
+ key, CSSM_ACL_AUTHORIZATION_MAC);
}
void ClientSession::verifyMac(const Context &context, KeyHandle key,
const CssmData &data, const CssmData &signature)
{
SendContext ctx(context);
- IPC(ucsp_client_verifyMac(UCSP_ARGS, CONTEXT(ctx), key,
- DATA(data), DATA(signature)));
+ IPCKEY(ucsp_client_verifyMac(UCSP_ARGS, CONTEXT(ctx), key,
+ DATA(data), DATA(signature)),
+ key, CSSM_ACL_AUTHORIZATION_MAC);
}
{
SendContext ctx(context);
DataOutput cipherOut(cipher, alloc);
- IPC(ucsp_client_encrypt(UCSP_ARGS, CONTEXT(ctx), key, DATA(clear), DATA(cipherOut)));
+ IPCKEY(ucsp_client_encrypt(UCSP_ARGS, CONTEXT(ctx), key, DATA(clear), DATA(cipherOut)),
+ key, CSSM_ACL_AUTHORIZATION_ENCRYPT);
}
void ClientSession::decrypt(const Context &context, KeyHandle key,
SendContext ctx(context);
DataOutput clearOut(clear, alloc);
- IPC(ucsp_client_decrypt(UCSP_ARGS, CONTEXT(ctx), key, DATA(cipher), DATA(clearOut)));
+ IPCKEY(ucsp_client_decrypt(UCSP_ARGS, CONTEXT(ctx), key, DATA(cipher), DATA(clearOut)),
+ key, CSSM_ACL_AUTHORIZATION_DECRYPT);
}
typedef CSSM_PKCS5_PBKDF2_PARAMS Params;
Copier<Params> params(param.interpretedAs<Params>(CSSM_ERRCODE_INVALID_INPUT_POINTER),
internalAllocator);
- IPC(ucsp_client_deriveKey(UCSP_ARGS, db, CONTEXT(ctx), baseKey,
+ IPCKEY(ucsp_client_deriveKey(UCSP_ARGS, db, CONTEXT(ctx), baseKey,
COPY(creds), COPY(proto), COPY(params), DATA(paramOutput),
- keyUsage, keyAttr, &newKey, &newHeader));
+ keyUsage, keyAttr, &newKey, &newHeader),
+ baseKey, CSSM_ACL_AUTHORIZATION_DERIVE);
break; }
default: {
- IPC(ucsp_client_deriveKey(UCSP_ARGS, db, CONTEXT(ctx), baseKey,
+ IPCKEY(ucsp_client_deriveKey(UCSP_ARGS, db, CONTEXT(ctx), baseKey,
COPY(creds), COPY(proto),
param.data(), param.length(), param.data(),
DATA(paramOutput),
- keyUsage, keyAttr, &newKey, &newHeader));
+ keyUsage, keyAttr, &newKey, &newHeader),
+ baseKey, CSSM_ACL_AUTHORIZATION_DERIVE);
break; }
}
}
SendContext ctx(context);
Copier<AccessCredentials> creds(cred, internalAllocator);
DataOutput keyData(wrappedKey, alloc);
- IPC(ucsp_client_wrapKey(UCSP_ARGS, CONTEXT(ctx), wrappingKey, COPY(creds),
+ /* @@@ When <rdar://problem/3525664>: CSSM_WrapKey doesn't check the acl of the key doing the wrapping. is fixed, we need to potentially edit the CSSM_ACL_AUTHORIZATION_ENCRYPT acl of the wrapping key as opposed to the key being wrapped. We need to know which of the 2 keys to edit though somehow. */
+ IPCKEY(ucsp_client_wrapKey(UCSP_ARGS, CONTEXT(ctx), wrappingKey, COPY(creds),
keyToBeWrapped, OPTIONALDATA(descriptiveData),
- &wrappedKey, DATA(keyData)));
+ &wrappedKey, DATA(keyData)),
+ keyToBeWrapped,
+ context.algorithm() == CSSM_ALGID_NONE
+ ? CSSM_ACL_AUTHORIZATION_EXPORT_CLEAR : CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED);
wrappedKey = CssmData(); // null out data section (force allocation for key data)
}
DataOutput descriptor(descriptiveData, alloc);
Copier<AccessCredentials> creds(cred, internalAllocator);
Copier<AclEntryPrototype> proto(&acl->proto(), internalAllocator);
- IPC(ucsp_client_unwrapKey(UCSP_ARGS, db, CONTEXT(ctx), key,
+ IPCKEY(ucsp_client_unwrapKey(UCSP_ARGS, db, CONTEXT(ctx), key,
COPY(creds), COPY(proto),
publicKey, wrappedKey, DATA(wrappedKey), usage, attr, DATA(descriptor),
- &newKey, &newHeader));
+ &newKey, &newHeader),
+ key, CSSM_ACL_AUTHORIZATION_DECRYPT);
}
Copier<AccessCredentials> creds(&cred, internalAllocator);
//@@@ ignoring callback
Copier<AclEntryInput> newEntry(edit.newEntry(), internalAllocator);
- IPC(ucsp_client_changeAcl(UCSP_ARGS, kind, key, COPY(creds),
- edit.mode(), edit.handle(), COPY(newEntry)));
+ IPCKEY(ucsp_client_changeAcl(UCSP_ARGS, kind, key, COPY(creds),
+ edit.mode(), edit.handle(), COPY(newEntry)),
+ key, CSSM_ACL_AUTHORIZATION_CHANGE_ACL);
}
void ClientSession::getOwner(AclKind kind, KeyHandle key, AclOwnerPrototype &owner,
{
Copier<AccessCredentials> creds(&cred, internalAllocator);
Copier<AclOwnerPrototype> protos(&proto, internalAllocator);
- IPC(ucsp_client_setOwner(UCSP_ARGS, kind, key, COPY(creds), COPY(protos)));
+ IPCKEY(ucsp_client_setOwner(UCSP_ARGS, kind, key, COPY(creds), COPY(protos)),
+ key, CSSM_ACL_AUTHORIZATION_CHANGE_OWNER);
}
#define IPCN(statement) \
{ CSSM_RETURN rcode; check(statement); if (rcode != CSSM_OK) CssmError::throwMe(rcode); }
#define IPC(statement) { activate(); IPCN(statement); }
+#define IPCKEY(statement, key, tag) \
+{ \
+ activate(); \
+ CSSM_RETURN rcode; \
+ for (bool retried = false;; retried = true) \
+ { \
+ check(statement); \
+ if (retried || rcode != CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT) \
+ break; \
+ addApplicationAclSubject(key, tag); \
+ } \
+ if (rcode != CSSM_OK) \
+ CssmError::throwMe(rcode); \
+}
// pass mandatory or optional CssmData arguments into an IPC call
#define DATA(arg) arg.data(), arg.length()
#include <Security/keychainacl.h>
#include <Security/cssmwalkers.h>
#include <Security/cssmdata.h>
+#include <Security/cssmclient.h>
namespace Security {
namespace CssmClient {
+static inline void check(CSSM_RETURN rc)
+{
+ ObjectImpl::check(rc);
+}
+
+
//
// AclBearer methods (trivial)
//
//
-// Delete an ACL by handle
+// Variant forms of AclBearer implemented in terms of its canonical virtual methods
//
void AclBearer::addAcl(const AclEntryInput &input, const CSSM_ACCESS_CREDENTIALS *cred)
{
}
+//
+// KeyAclBearer implementation
+//
+void KeyAclBearer::getAcl(AutoAclEntryInfoList &aclInfos, const char *selectionTag) const
+{
+ aclInfos.allocator(allocator);
+ check(CSSM_GetKeyAcl(csp, &key, reinterpret_cast<const CSSM_STRING *>(selectionTag), aclInfos, aclInfos));
+}
+
+void KeyAclBearer::changeAcl(const CSSM_ACL_EDIT &aclEdit, const CSSM_ACCESS_CREDENTIALS *cred)
+{
+ check(CSSM_ChangeKeyAcl(csp, AccessCredentials::needed(cred), &aclEdit, &key));
+}
+
+void KeyAclBearer::getOwner(AutoAclOwnerPrototype &owner) const
+{
+ owner.allocator(allocator);
+ check(CSSM_GetKeyOwner(csp, &key, owner));
+}
+
+void KeyAclBearer::changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner,
+ const CSSM_ACCESS_CREDENTIALS *cred)
+{
+ check(CSSM_ChangeKeyOwner(csp, AccessCredentials::needed(cred), &key, &newOwner));
+}
+
+
//
// A single global structure containing pseudo-static data
//
};
+//
+// An AclBearer applied to a raw CSSM key
+//
+class KeyAclBearer : public AclBearer {
+public:
+ KeyAclBearer(CSSM_CSP_HANDLE cspH, CSSM_KEY &theKey, CssmAllocator &alloc)
+ : csp(cspH), key(theKey), allocator(alloc) { }
+
+ const CSSM_CSP_HANDLE csp;
+ CSSM_KEY &key;
+ CssmAllocator &allocator;
+
+protected:
+ void getAcl(AutoAclEntryInfoList &aclInfos,
+ const char *selectionTag = NULL) const;
+ void changeAcl(const CSSM_ACL_EDIT &aclEdit,
+ const CSSM_ACCESS_CREDENTIALS *cred = NULL);
+ void getOwner(AutoAclOwnerPrototype &owner) const;
+ void changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner,
+ const CSSM_ACCESS_CREDENTIALS *cred = NULL);
+};
+
+
//
// An AclFactory helps create and maintain CSSM-layer AccessCredentials
// and matching samples. There is state in an AclFactory, though simple
CssmDataContainer plainText1(allocator);
CssmDataContainer plainText2(allocator);
- try
- {
- // Decrypt the data
- // @@@ Don't use staged decrypt once the AppleCSPDL can do combo
- // encryption.
- // Setup decryption context
- Decrypt decrypt(csp(), algorithm());
- decrypt.mode(CSSM_ALGMODE_CBCPadIV8);
- decrypt.padding(CSSM_PADDING_PKCS1);
- decrypt.initVector(iv);
- decrypt.key(Key(this));
- decrypt.cred(AccessCredentials::overlay(cred));
- decrypt.decrypt(&cipherText, 1, &plainText1, 1);
- decrypt.final(plainText2);
- }
- catch (const CssmError &e)
- {
- if (e.cssmError() != CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT)
- throw;
- // The user checked to don't ask again checkbox in the rogue app alert. Let's edit the ACL for this key and add the calling application to it.
- Key key(this); // the underlying key
- SecPointer<Access> access = new Access(*key); // extract access rights
- SecPointer<TrustedApplication> thisApp = new TrustedApplication;
- access->addApplicationToRight(CSSM_ACL_AUTHORIZATION_DECRYPT, thisApp.get()); // add this app
- access->setAccess(*key, true); // commit
-
- // Retry the decrypt operation.
- Decrypt decrypt(csp(), algorithm());
- decrypt.mode(CSSM_ALGMODE_CBCPadIV8);
- decrypt.padding(CSSM_PADDING_PKCS1);
- decrypt.initVector(iv);
- decrypt.key(Key(this));
- decrypt.cred(AccessCredentials::overlay(cred));
- decrypt.decrypt(&cipherText, 1, &plainText1, 1);
- decrypt.final(plainText2);
- }
+ // Decrypt the data
+ // @@@ Don't use staged decrypt once the AppleCSPDL can do combo
+ // encryption.
+ // Setup decryption context
+ Decrypt decrypt(csp(), algorithm());
+ decrypt.mode(CSSM_ALGMODE_CBCPadIV8);
+ decrypt.padding(CSSM_PADDING_PKCS1);
+ decrypt.initVector(iv);
+ decrypt.key(Key(this));
+ decrypt.cred(AccessCredentials::overlay(cred));
+ decrypt.decrypt(&cipherText, 1, &plainText1, 1);
+ decrypt.final(plainText2);
// Use DL allocator for allocating memory for data.
uint32 length = plainText1.Length + plainText2.Length;
// Free the ioKey, erase keyReference from mKeyMap, and delete the ReferencedKey
void freeKey(CssmAllocator &allocator, CSSM_KEY &key);
-private:
+protected:
// Called by the constructor of ReferencedKey -- add referencedKey to mKeyMap
void add(ReferencedKey &referencedKey);
// Erase keyReference from mKeyMap, and return it (for deletion)
ReferencedKey &erase(ReferencedKey::KeyReference keyReference);
-private:
+protected:
typedef map<ReferencedKey::KeyReference, ReferencedKey *> KeyMap;
KeyMap mKeyMap;
mutable Mutex mKeyMapLock;
// we must force THREAD_NDEBUG to off while compiling our header. Trust me.
//
#include <Security/threading.h>
+#include <Security/globalizer.h>
#include <Security/memutils.h>
bool Mutex::debugHasInitialized;
bool Mutex::loggingMutexi;
-Mutex::Mutex(bool log)
+inline void Mutex::init(Type type, bool log)
{
#if !defined(THREAD_NDEBUG)
// this debug-setup code isn't interlocked, but it's idempotent
#else
debugLog = false;
#endif //THREAD_NDEBUG
+}
+
+struct Recursive : public pthread_mutexattr_t {
+ Recursive()
+ {
+ pthread_mutexattr_init(this);
+ pthread_mutexattr_settype(this, PTHREAD_MUTEX_RECURSIVE);
+ }
+};
+
+
+Mutex::Mutex(bool log)
+{
+ init(normal, log);
check(pthread_mutex_init(&me, NULL));
}
+Mutex::Mutex(Type type, bool log)
+{
+ init(type, log);
+ switch (type) {
+ case normal:
+ check(pthread_mutex_init(&me, NULL));
+ break;
+ case recursive:
+ static ModuleNexus<Recursive> recursive;
+ check(pthread_mutex_init(&me, &recursive()));
+ };
+ }
+
Mutex::~Mutex()
{
#if !defined(THREAD_NDEBUG)
void check(int err) { if (err) UnixError::throwMe(err); }
public:
+ enum Type {
+ normal,
+ recursive
+ };
+
Mutex(bool log = true);
+ Mutex(Type type, bool log = true);
~Mutex();
void lock();
bool tryLock();
unsigned long contentionCount; // number of contentions (valid only if debugLog)
static bool debugHasInitialized; // global: debug state set up
static bool loggingMutexi; // global: we are debug-logging mutexi
+
+ void init(Type type, bool log);
};
#elif _USE_THREADS == _USE_NO_THREADS