diff --git a/.gitignore b/.gitignore index ff4787a95..b1d0c9e1e 100644 --- a/.gitignore +++ b/.gitignore @@ -195,6 +195,7 @@ tags /lib/gssapi/gsstool /lib/gssapi/krb5/gsskrb5-private.h /lib/gssapi/ntlm/ntlm-private.h +/lib/gssapi/sanon/sanon-private.h /lib/gssapi/spnego/spnego-private.h /lib/gssapi/test_acquire_cred /lib/gssapi/test_add_store_cred diff --git a/doc/standardisation/draft-howard-gss-sanon-12.txt b/doc/standardisation/draft-howard-gss-sanon-12.txt new file mode 100644 index 000000000..7cafc9cc0 --- /dev/null +++ b/doc/standardisation/draft-howard-gss-sanon-12.txt @@ -0,0 +1,560 @@ + + + + +Network Working Group L. Howard +Internet-Draft PADL +Intended status: Informational April 23, 2020 +Expires: October 25, 2020 + + + A Simple Anonymous GSS-API Mechanism + draft-howard-gss-sanon-12 + +Abstract + + This document defines protocols, procedures and conventions for a + Generic Security Service Application Program Interface (GSS-API) + security mechanism that provides key agreement without authentication + of either party. + +Status of This Memo + + This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79. + + Internet-Drafts are working documents of the Internet Engineering + Task Force (IETF). Note that other groups may also distribute + working documents as Internet-Drafts. The list of current Internet- + Drafts is at https://datatracker.ietf.org/drafts/current/. + + Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress." + + This Internet-Draft will expire on October 25, 2020. + +Copyright Notice + + Copyright (c) 2020 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. Code Components extracted from this document must + include Simplified BSD License text as described in Section 4.e of + the Trust Legal Provisions and are provided without warranty as + described in the Simplified BSD License. + + + + +Howard Expires October 25, 2020 [Page 1] + +Internet-Draft SAnon GSS-API Mechanism April 2020 + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. Requirements notation . . . . . . . . . . . . . . . . . . . . 2 + 3. Discovery and Negotiation . . . . . . . . . . . . . . . . . . 3 + 4. Naming . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 + 4.1. Mechanism Names . . . . . . . . . . . . . . . . . . . . . . 3 + 4.2. Display Name Format . . . . . . . . . . . . . . . . . . . . 3 + 4.3. Exported Name Format . . . . . . . . . . . . . . . . . . . 3 + 5. Definitions and Token Formats . . . . . . . . . . . . . . . . 4 + 5.1. Context Establishment Tokens . . . . . . . . . . . . . . . 4 + 5.1.1. Initial context token . . . . . . . . . . . . . . . . . . 4 + 5.1.2. Acceptor context token . . . . . . . . . . . . . . . . . 5 + 5.1.3. Initiator context completion . . . . . . . . . . . . . . 5 + 5.2. Per-Message Tokens . . . . . . . . . . . . . . . . . . . . 6 + 5.3. Context Deletion Tokens . . . . . . . . . . . . . . . . . . 6 + 6. Key derivation . . . . . . . . . . . . . . . . . . . . . . . 6 + 7. Pseudo-Random Function . . . . . . . . . . . . . . . . . . . 7 + 8. Security Considerations . . . . . . . . . . . . . . . . . . . 7 + 9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 7 + 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 7 + 10.1. Normative References . . . . . . . . . . . . . . . . . . . 7 + 10.2. Informative References . . . . . . . . . . . . . . . . . . 8 + Appendix A. Test Vectors . . . . . . . . . . . . . . . . . . . . 9 + Appendix B. Mechanism Attributes . . . . . . . . . . . . . . . . 9 + Appendix C. NegoEx . . . . . . . . . . . . . . . . . . . . . . . 10 + Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 10 + +1. Introduction + + The Generic Security Service Application Program Interface (GSS-API) + [RFC2743] provides a framework for authentication and message + protection services through a common programming interface. + + The Simple Anonymous mechanism (hereafter SAnon) described in this + document is a simple protocol based on the X25519 elliptic curve + Diffie-Hellman (ECDH) key agreement scheme defined in [RFC7748]. No + authentication of initiator or acceptor is provided. A potential use + of SAnon is to provide a degree of privacy when bootstrapping unkeyed + entities. + +2. Requirements notation + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in [RFC2119]. + + + + + +Howard Expires October 25, 2020 [Page 2] + +Internet-Draft SAnon GSS-API Mechanism April 2020 + + +3. Discovery and Negotiation + + The SAnon mechanism is identified by the following OID: + + sanon-x25519 OBJECT IDENTIFIER ::= + {iso(1)identified-organization(3)dod(6)internet(1) + private(4)enterprise(1)padl(5322)gss-sanon(26) + mechanisms(1)sanon-x25519(110)} + + The means of discovering GSS-API peers and their supported mechanisms + is out of this specification's scope. To avoid multiple layers of + negotiation, SAnon is not crypto-agile; a future variant using a + different algorithm would be assigned a different OID. + + If anonymity is not desired then SAnon MUST NOT be used. Either + party can test for anon_state (GSS_C_ANON_FLAG) to check if anonymous + authentication was performed. + +4. Naming + +4.1. Mechanism Names + + A SAnon mechanism name is abstractly a boolean indicating whether it + represents an anonymous identity. Anonymous identities are names + imported with the GSS_C_NT_ANONYMOUS name type. Implementations MAY + map other names to anonymous identities according to local policy. + Names representing non-anonymous identities MUST be importable so + that initiators with non-default credentials can engage SAnon by + setting anon_req_flag (GSS_C_ANON_FLAG). + +4.2. Display Name Format + + When GSS_Display_name() is called on a mechanism name representing an + anonymous identity, the display string is WELLKNOWN/ + ANONYMOUS@WELLKNOWN:ANONYMOUS [RFC8062] and the name type is + GSS_C_NT_ANONYMOUS. This is always the name observed by a SAnon + peer. All context APIs that return peer names MUST return this name + for both parties if the context is established. + +4.3. Exported Name Format + + SAnon uses the mechanism-independent exported name object format + defined in [RFC2743] Section 3.2. All lengths are encoded as big- + endian integers. The export of non-anonymous mechanism names MUST + fail with GSS_S_BAD_NAME. + + + + + + +Howard Expires October 25, 2020 [Page 3] + +Internet-Draft SAnon GSS-API Mechanism April 2020 + + + +--------------+--------------+---------------------------------+ + | Length | Name | Description | + +--------------+--------------+---------------------------------+ + | 2 | TOK_ID | 04 01 | + | | | | + | 2 | MECH_OID_LEN | Length of the mechanism OID | + | | | | + | MECH_OID_LEN | MECH_OID | The SAnon mechanism OID, in DER | + | | | | + | 4 | NAME_LEN | 00 00 00 01 | + | | | | + | 1 | NAME | 01 | + +--------------+--------------+---------------------------------+ + +5. Definitions and Token Formats + +5.1. Context Establishment Tokens + +5.1.1. Initial context token + + The initial context token is framed per Section 1 of [RFC2743]: + + GSS-API DEFINITIONS ::= + BEGIN + + MechType ::= OBJECT IDENTIFIER -- 1.3.6.1.4.1.5322.26.1.110 + GSSAPI-Token ::= + [APPLICATION 0] IMPLICIT SEQUENCE { + thisMech MechType, + innerToken ANY DEFINED BY thisMech + -- 32 byte initiator public key + } + END + + On the first call to GSS_Init_sec_context(), the mechanism checks if + one or more of the following are true: + + The caller set anon_req_flag (GSS_C_ANON_FLAG) + + The claimant credential identity is anonymous (see Section 4.1) + + The claimant credential is the default one and target identity is + anonymous + + If none of these are the case, the call MUST fail with + GSS_S_UNAVAILABLE. + + + + + +Howard Expires October 25, 2020 [Page 4] + +Internet-Draft SAnon GSS-API Mechanism April 2020 + + + If proceeding, the initiator generates a fresh secret and public key + pair per [RFC7748] Section 6.1 and returns GSS_S_CONTINUE_NEEDED, + indicating that a subsequent context token from the acceptor is + expected. The innerToken field of the output_token contains the + initiator's 32 byte public key. + + Portable initiators are RECOMMENDED to use default credentials + whenever possible and request anonymity only through anon_req_flag + (see [RFC8062] Section 6). + +5.1.2. Acceptor context token + + Upon receiving a context token from the initiator, the acceptor + validates that the token is well formed and contains a public key of + the requisite length. The acceptor generates a fresh secret and + public key pair. The context session key is computed as specified in + Section 6. + + The acceptor constructs an output_token by concatenating its public + key with the token emitted by calling GSS_GetMIC() with the default + QOP and zero-length octet string. The output token is sent to the + initiator without additional framing. + + The acceptor then returns GSS_S_COMPLETE, setting src_name to the + canonical anonymous name. The reply_det_state (GSS_C_REPLAY_FLAG), + sequence_state (GSS_C_SEQUENCE_FLAG), conf_avail (GSS_C_CONF_FLAG), + integ_avail (GSS_C_INTEG_FLAG) and anon_state (GSS_C_ANON_FLAG) + security context flags are set. The context is ready to use. + +5.1.3. Initiator context completion + + Upon receiving the acceptor context token and verifying it is well + formed, the initiator extracts the acceptor's public key (being the + first 32 bytes of the input token) and computes the context session + key per Section 6. + + The initiator calls GSS_VerifyMIC() with the MIC extracted from the + context token and the zero-length octet string. If successful, the + initiator returns GSS_S_COMPLETE to the caller, to indicate the + initiator is authenticated and the context is ready for use. No + output token is emitted. Supported security context flags are as for + the acceptor context. The flags returned to the caller are the + intersection of supported and requested flags, combined with + anon_state (GSS_C_ANON_FLAG) which is set unconditionally. + + + + + + + +Howard Expires October 25, 2020 [Page 5] + +Internet-Draft SAnon GSS-API Mechanism April 2020 + + +5.2. Per-Message Tokens + + The per-message tokens definitions are imported from [RFC4121] + Section 4.2. The base key used to derive specific keys for signing + and sealing messages is defined in Section 6. The [RFC3961] + encryption and checksum algorithms use the aes128-cts-hmac-sha256-128 + encryption type defined in [RFC8009]. The AcceptorSubkey flag as + defined in [RFC4121] Section 4.2.2 MUST be set. + +5.3. Context Deletion Tokens + + Context deletion tokens are empty in this mechanism. The behavior of + GSS_Delete_sec_context() [RFC2743] is as specified in [RFC4121] + Section 4.3. + +6. Key derivation + + The context session key is known as the base key, and is computed + using a key derivation function from [SP800-108] Section 5.1 (using + HMAC as the PRF): + + base key = HMAC-SHA-256(K1, i | label | 0x00 | context | L) + + where: + + K1 the output of X25519(local secret key, peer public key) + as specified in [RFC7748] Section 6.1 + + i the constant 0x00000001, representing the iteration + count expressed in big-endian binary representation of + 4 bytes + + label the string "sanon-x25519" (without quotation marks) + + context initiator public key | acceptor public key | channel + binding application data (if present) + + L the constant 0x00000080, being length in bits of the + key to be outputted expressed in big-endian binary + representation of 4 bytes + + The inclusion of channel bindings in the key derivation function + means that the acceptor cannot ignore initiator channel bindings; + this differs from some other mechanisms. + + The base key provides the acceptor-asserted subkey defined in + [RFC4121] Section 2 and is used to generate keys for per-message + tokens and the GSS-API PRF. Its encryption type is aes128-cts-hmac- + + + +Howard Expires October 25, 2020 [Page 6] + +Internet-Draft SAnon GSS-API Mechanism April 2020 + + + sha256-128 per [RFC8009]. The [RFC3961] algorithm protocol + parameters are as given in [RFC8009] Section 5. + +7. Pseudo-Random Function + + The [RFC4401] GSS-API pseudo-random function for this mechanism + imports the definitions from [RFC8009], using the base key for both + GSS_C_PRF_KEY_FULL and GSS_C_PRF_KEY_PARTIAL usages. + +8. Security Considerations + + This document defines a GSS-API security mechanism, and therefore + deals in security and has security considerations text embedded + throughout. This section only addresses security considerations + associated with the SAnon mechanism described in this document. It + does not address security considerations associated with the GSS-API + itself. + + This mechanism provides only for key agreement. It does not + authenticate the identity of either party. It MUST NOT be selected + if either party requires identification of its peer. + + SAnon mechanism names are not unary. Implementations MUST ensure + that GSS_Compare_name() always sets name_equal to FALSE when + comparing mechanism names. + +9. Acknowledgements + + AuriStor, Inc funded the design of this protocol, along with an + implementation for the Heimdal GSS-API library. + + Jeffrey Altman, Greg Hudson, Simon Josefsson, and Nicolas Williams + provided valuable feedback on this document. + +10. References + +10.1. Normative References + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, + DOI 10.17487/RFC2119, March 1997, + . + + [RFC2743] Linn, J., "Generic Security Service Application Program + Interface Version 2, Update 1", RFC 2743, + DOI 10.17487/RFC2743, January 2000, + . + + + + +Howard Expires October 25, 2020 [Page 7] + +Internet-Draft SAnon GSS-API Mechanism April 2020 + + + [RFC3961] Raeburn, K., "Encryption and Checksum Specifications for + Kerberos 5", RFC 3961, DOI 10.17487/RFC3961, February + 2005, . + + [RFC4121] Zhu, L., Jaganathan, K., and S. Hartman, "The Kerberos + Version 5 Generic Security Service Application Program + Interface (GSS-API) Mechanism: Version 2", RFC 4121, + DOI 10.17487/RFC4121, July 2005, + . + + [RFC4401] Williams, N., "A Pseudo-Random Function (PRF) API + Extension for the Generic Security Service Application + Program Interface (GSS-API)", RFC 4401, + DOI 10.17487/RFC4401, February 2006, + . + + [RFC7748] Langley, A., Hamburg, M., and S. Turner, "Elliptic Curves + for Security", RFC 7748, DOI 10.17487/RFC7748, January + 2016, . + + [RFC8009] Jenkins, M., Peck, M., and K. Burgin, "AES Encryption with + HMAC-SHA2 for Kerberos 5", RFC 8009, DOI 10.17487/RFC8009, + October 2016, . + +10.2. Informative References + + [I-D.zhu-negoex] + Short, M., Zhu, L., Damour, K., and D. McPherson, "SPNEGO + Extended Negotiation (NEGOEX) Security Mechanism", draft- + zhu-negoex-04 (work in progress), January 2011. + + [RFC4178] Zhu, L., Leach, P., Jaganathan, K., and W. Ingersoll, "The + Simple and Protected Generic Security Service Application + Program Interface (GSS-API) Negotiation Mechanism", + RFC 4178, DOI 10.17487/RFC4178, October 2005, + . + + [RFC4757] Jaganathan, K., Zhu, L., and J. Brezak, "The RC4-HMAC + Kerberos Encryption Types Used by Microsoft Windows", + RFC 4757, DOI 10.17487/RFC4757, December 2006, + . + + [RFC5587] Williams, N., "Extended Generic Security Service Mechanism + Inquiry APIs", RFC 5587, DOI 10.17487/RFC5587, July 2009, + . + + + + + + +Howard Expires October 25, 2020 [Page 8] + +Internet-Draft SAnon GSS-API Mechanism April 2020 + + + [RFC8062] Zhu, L., Leach, P., Hartman, S., and S. Emery, Ed., + "Anonymity Support for Kerberos", RFC 8062, + DOI 10.17487/RFC8062, February 2017, + . + + [SP800-108] + Chen, L., "Recommendation for Key Derivation Using + Pseudorandom Functions (Revised)", October 2009. + +Appendix A. Test Vectors + + initiator secret key 69 df cc 04 2b 7a 33 f8 1a 43 fb f0 33 0a b5 3f + bc 20 e6 c1 4f f8 26 ce 6a 4d bc 8c 6e e4 2b a9 + + initiator public key d2 1e 3e 58 60 b0 16 6c d1 cb 38 1a aa 89 62 93 + 07 13 ae e1 76 86 93 10 46 57 a7 a1 9c 1d 76 2e + + initiator token 60 2c 06 0a 2b 06 01 04 01 a9 4a 1a 01 6e d2 1e + 3e 58 60 b0 16 6c d1 cb 38 1a aa 89 62 93 07 13 + ae e1 76 86 93 10 46 57 a7 a1 9c 1d 76 2e + + acceptor secret key 3e 4f e6 5b ea 85 94 3b 5a a2 b7 83 f6 26 84 1a + 10 39 d5 d3 6d af 85 aa a1 6f 12 97 57 99 6c ff + + acceptor public key a8 32 14 9d 58 33 13 ce 1c 55 7b 2b d1 8a e7 a5 + 59 8c a6 4b 02 20 83 5e 16 be 09 ca 2f 90 60 31 + + base key af f1 8d b7 45 c6 27 cd a8 da d4 9b d7 e7 01 25 + + acceptor token a8 32 14 9d 58 33 13 ce 1c 55 7b 2b d1 8a e7 a5 + 59 8c a6 4b 02 20 83 5e 16 be 09 ca 2f 90 60 31 + 04 04 05 ff ff ff ff ff 00 00 00 00 00 00 00 00 + 45 02 7b a8 15 1c 33 05 22 bb c4 36 84 d2 e1 8c + +Appendix B. Mechanism Attributes + + The [RFC5587] mechanism attributes for this mechanism are: + + GSS_C_MA_MECH_CONCRETE + + GSS_C_MA_ITOK_FRAMED + + GSS_C_MA_AUTH_INIT_ANON + + GSS_C_MA_AUTH_TARG_ANON + + GSS_C_MA_INTEG_PROT + + + + +Howard Expires October 25, 2020 [Page 9] + +Internet-Draft SAnon GSS-API Mechanism April 2020 + + + GSS_C_MA_CONF_PROT + + GSS_C_MA_MIC + + GSS_C_MA_WRAP + + GSS_C_MA_REPLAY_DET + + GSS_C_MA_OOS_DET + + GSS_C_MA_CBINDINGS + + GSS_C_MA_PFS + + GSS_C_MA_CTX_TRANS + +Appendix C. NegoEx + + When SAnon is negotiated by [I-D.zhu-negoex], the authentication + scheme identifier is DEE384FF-1086-4E86-BE78-B94170BFD376. + + The initiator and acceptor keys for NegoEx checksum generation and + verification are derived using the GSS-API PRF (see Section 7), with + the input data "sanon-x25519-initiator-negoex-key" and "sanon-x25519- + acceptor-negoex-key" respectively (without quotation marks). + + The initiator metadata, if present, contains a set of GSS-API flags + encoded as a 4 byte little endian integer. This is used to convey to + the acceptor any Windows-specific GSS-API flags (see [RFC4757] + Section 7.1). Other GSS-API flags MUST NOT be present in the + metadata. + + It is RECOMMENDED that GSS-API implementations supporting both SPNEGO + [RFC4178] and NegoEx advertise SAnon under both to maximise + interoperability. + +Author's Address + + Luke Howard + PADL Software Pty Ltd + PO Box 59 + Central Park, VIC 3145 + Australia + + Email: lukeh@padl.com + + + + + + +Howard Expires October 25, 2020 [Page 10] diff --git a/lib/gssapi/Makefile.am b/lib/gssapi/Makefile.am index 0b1c7ff32..7263c5230 100644 --- a/lib/gssapi/Makefile.am +++ b/lib/gssapi/Makefile.am @@ -12,6 +12,7 @@ AM_CPPFLAGS += \ -I$(srcdir)/ntlm \ -I$(srcdir)/krb5 \ -I$(srcdir)/spnego \ + -I$(srcdir)/sanon \ $(INCLUDE_libintl) lib_LTLIBRARIES = libgssapi.la test_negoex_mech.la @@ -215,11 +216,45 @@ ntlmsrc = \ $(srcdir)/ntlm/ntlm-private.h: $(ntlmsrc) cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p ntlm/ntlm-private.h $(ntlmsrc) || rm -f ntlm/ntlm-private.h +sanonsrc = \ + sanon/accept_sec_context.c \ + sanon/acquire_cred.c \ + sanon/add_cred.c \ + sanon/canonicalize_name.c \ + sanon/compare_name.c \ + sanon/context_time.c \ + sanon/crypto.c \ + sanon/delete_sec_context.c \ + sanon/display_name.c \ + sanon/display_status.c \ + sanon/duplicate_cred.c \ + sanon/duplicate_name.c \ + sanon/export_name.c \ + sanon/export_cred.c \ + sanon/export_sec_context.c \ + sanon/external.c \ + sanon/import_cred.c \ + sanon/import_name.c \ + sanon/import_sec_context.c \ + sanon/init_sec_context.c \ + sanon/inquire_context.c \ + sanon/inquire_cred.c \ + sanon/inquire_cred_by_mech.c \ + sanon/inquire_mechs_for_name.c \ + sanon/inquire_names_for_mech.c \ + sanon/inquire_sec_context_by_oid.c \ + sanon/negoex.c \ + sanon/process_context_token.c \ + sanon/release_cred.c \ + sanon/release_name.c \ + sanon/sanon-private.h + dist_libgssapi_la_SOURCES = \ $(krb5src) \ $(mechsrc) \ $(ntlmsrc) \ - $(spnegosrc) + $(spnegosrc) \ + $(sanonsrc) nodist_libgssapi_la_SOURCES = \ gkrb5_err.c \ @@ -252,6 +287,7 @@ noinst_HEADERS = \ gssapi_mech.h \ $(srcdir)/ntlm/ntlm-private.h \ $(srcdir)/spnego/spnego-private.h \ + $(srcdir)/sanon/sanon-private.h \ $(srcdir)/krb5/gsskrb5-private.h nobase_include_HEADERS = \ @@ -281,6 +317,7 @@ spnego_files = \ BUILTHEADERS = \ $(srcdir)/krb5/gsskrb5-private.h \ $(srcdir)/spnego/spnego-private.h \ + $(srcdir)/sanon/sanon-private.h \ $(srcdir)/ntlm/ntlm-private.h $(libgssapi_la_OBJECTS): $(BUILTHEADERS) @@ -315,6 +352,8 @@ $(srcdir)/krb5/gsskrb5-private.h: $(srcdir)/spnego/spnego-private.h: cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p spnego/spnego-private.h $(spnegosrc) || rm -f spnego/spnego-private.h +$(srcdir)/sanon/sanon-private.h: + cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p sanon/sanon-private.h $(sanonsrc) || rm -f sanon/sanon-private.h TESTS = test_oid test_names test_cfx # test_sequence diff --git a/lib/gssapi/NTMakefile b/lib/gssapi/NTMakefile index 185f63c40..2c5975c04 100644 --- a/lib/gssapi/NTMakefile +++ b/lib/gssapi/NTMakefile @@ -228,6 +228,38 @@ ntlmsrc = \ ntlm/set_sec_context_option.c \ ntlm/kdc.c +sanonsrc = \ + sanon/accept_sec_context.c \ + sanon/acquire_cred.c \ + sanon/add_cred.c \ + sanon/canonicalize_name.c \ + sanon/compare_name.c \ + sanon/context_time.c \ + sanon/crypto.c \ + sanon/delete_sec_context.c \ + sanon/display_name.c \ + sanon/display_status.c \ + sanon/duplicate_cred.c \ + sanon/duplicate_name.c \ + sanon/export_cred.c \ + sanon/export_name.c \ + sanon/export_sec_context.c \ + sanon/external.c \ + sanon/import_cred.c \ + sanon/import_name.c \ + sanon/import_sec_context.c \ + sanon/init_sec_context.c \ + sanon/inquire_context.c \ + sanon/inquire_cred.c \ + sanon/inquire_cred_by_mech.c \ + sanon/inquire_mechs_for_name.c \ + sanon/inquire_names_for_mech.c \ + sanon/inquire_sec_context_by_oid.c \ + sanon/negoex.c \ + sanon/process_context_token.c \ + sanon/release_cred.c \ + sanon/release_name.c + $(OBJ)\ntlm\ntlm-private.h: $(ntlmsrc) $(PERL) ../../cf/make-proto.pl -q -P remove -p $@ $(ntlmsrc) @@ -237,6 +269,9 @@ $(OBJ)\krb5\gsskrb5-private.h: $(krb5src) $(OBJ)\spnego\spnego-private.h: $(spnegosrc) $(PERL) ../../cf/make-proto.pl -q -P remove -p $@ $(spnegosrc) +$(OBJ)\sanon\sanon-private.h: $(sanonsrc) + $(PERL) ../../cf/make-proto.pl -q -P remove -p $@ $(sanonsrc) + gssapi_files = $(OBJ)\gssapi\asn1_gssapi_asn1.x spnego_files = $(OBJ)\spnego\asn1_spnego_asn1.x @@ -280,6 +315,7 @@ INCFILES= \ $(INCDIR)\gssapi\gkrb5_err.h \ $(OBJ)\ntlm\ntlm-private.h \ $(OBJ)\spnego\spnego-private.h \ + $(OBJ)\sanon\sanon-private.h \ $(OBJ)\krb5\gsskrb5-private.h \ $(OBJ)\gkrb5_err.h \ $(OBJ)\negoex_err.h \ @@ -465,6 +501,36 @@ libgssapi_OBJs = \ $(OBJ)\ntlm/release_name.obj \ $(OBJ)\ntlm/set_sec_context_option.obj \ $(OBJ)\ntlm/kdc.obj \ + $(OBJ)\sanon/accept_sec_context.obj \ + $(OBJ)\sanon/acquire_cred.obj \ + $(OBJ)\sanon/add_cred.obj \ + $(OBJ)\sanon/canonicalize_name.obj \ + $(OBJ)\sanon/compare_name.obj \ + $(OBJ)\sanon/context_time.obj \ + $(OBJ)\sanon/crypto.obj \ + $(OBJ)\sanon/delete_sec_context.obj \ + $(OBJ)\sanon/display_name.obj \ + $(OBJ)\sanon/display_status.obj \ + $(OBJ)\sanon/duplicate_cred.obj \ + $(OBJ)\sanon/duplicate_name.obj \ + $(OBJ)\sanon/export_cred.obj \ + $(OBJ)\sanon/export_name.obj \ + $(OBJ)\sanon/export_sec_context.obj \ + $(OBJ)\sanon/external.obj \ + $(OBJ)\sanon/import_cred.obj \ + $(OBJ)\sanon/import_name.obj \ + $(OBJ)\sanon/import_sec_context.obj \ + $(OBJ)\sanon/init_sec_context.obj \ + $(OBJ)\sanon/inquire_context.obj \ + $(OBJ)\sanon/inquire_cred.obj \ + $(OBJ)\sanon/inquire_cred_by_mech.obj \ + $(OBJ)\sanon/inquire_mechs_for_name.obj \ + $(OBJ)\sanon/inquire_names_for_mech.obj \ + $(OBJ)\sanon/inquire_sec_context_by_oid.obj \ + $(OBJ)\sanon/negoex.obj \ + $(OBJ)\sanon/process_context_token.obj \ + $(OBJ)\sanon/release_cred.obj \ + $(OBJ)\sanon/release_name.obj \ $(OBJ)\gkrb5_err.obj \ $(OBJ)\negoex_err.obj \ $(spnego_files:.x=.obj) \ @@ -496,6 +562,12 @@ GCOPTS=-I$(SRCDIR) -I$(OBJ) -Igssapi -DBUILD_GSSAPI_LIB {spnego}.c{$(OBJ)\spnego}.obj:: $(C2OBJ_NP) -Fo$(OBJ)\spnego\ -Fd$(OBJ)\spnego\ -I$(OBJ)\spnego -Imech $(GCOPTS) -DASN1_LIB +{$(OBJ)\sanon}.c{$(OBJ)\sanon}.obj:: + $(C2OBJ_NP) -Fo$(OBJ)\sanon\ -Fd$(OBJ)\sanon\ -I$(OBJ)\sanon -I$(OBJ) -I$(OBJ)\krb5 -I$(OBJ)\gssapi -Ikrb5 -Imech -Igssapi $(GCOPTS) + +{sanon}.c{$(OBJ)\sanon}.obj:: + $(C2OBJ_NP) -Fo$(OBJ)\sanon\ -Fd$(OBJ)\sanon\ -I$(OBJ)\sanon -I$(OBJ) -I$(OBJ)\krb5 -I$(OBJ)\gssapi -Ikrb5 -Imech -Igssapi $(GCOPTS) -DASN1_LIB + {$(OBJ)\gssapi}.c{$(OBJ)\gssapi}.obj:: $(C2OBJ_NP) -Fo$(OBJ)\gssapi\ -Fd$(OBJ)\gssapi\ -I$(OBJ)\gssapi $(GCOPTS) @@ -577,6 +649,9 @@ mkdirs-gss: !if !exist($(OBJ)\spnego) $(MKDIR) $(OBJ)\spnego !endif +!if !exist($(OBJ)\sanon) + $(MKDIR) $(OBJ)\sanon +!endif !if !exist($(OBJ)\mech) $(MKDIR) $(OBJ)\mech !endif @@ -589,6 +664,7 @@ clean:: -$(RM) $(OBJ)\krb5\*.* -$(RM) $(OBJ)\spnego\*.* -$(RM) $(OBJ)\mech\*.* + -$(RM) $(OBJ)\sanon\*.* -$(RM) $(OBJ)\gssapi\*.* all-tools:: $(BINDIR)\gsstool.exe diff --git a/lib/gssapi/gssapi/gssapi_oid.h b/lib/gssapi/gssapi/gssapi_oid.h index 55054858d..fabd090fd 100644 --- a/lib/gssapi/gssapi/gssapi_oid.h +++ b/lib/gssapi/gssapi/gssapi_oid.h @@ -166,6 +166,9 @@ extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ntlm_reset_crypto_oid_desc; extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_negoex_mechanism_oid_desc; #define GSS_NEGOEX_MECHANISM (&__gss_negoex_mechanism_oid_desc) +extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_sanon_x25519_mechanism_oid_desc; +#define GSS_SANON_X25519_MECHANISM (&__gss_sanon_x25519_mechanism_oid_desc) + /* * OID mappings with name and short description and and slightly longer description */ diff --git a/lib/gssapi/gssapi_mech.h b/lib/gssapi/gssapi_mech.h index 07682ca7f..634e16b32 100644 --- a/lib/gssapi/gssapi_mech.h +++ b/lib/gssapi/gssapi_mech.h @@ -636,6 +636,7 @@ _gss_mg_support_mechanism(gss_const_OID mech); gssapi_mech_interface __gss_spnego_initialize(void); gssapi_mech_interface __gss_krb5_initialize(void); gssapi_mech_interface __gss_ntlm_initialize(void); +gssapi_mech_interface __gss_sanon_initialize(void); void gss_mg_collect_error(gss_OID, OM_uint32, OM_uint32); diff --git a/lib/gssapi/libgssapi-exports.def b/lib/gssapi/libgssapi-exports.def index f1edb983f..10e487f13 100644 --- a/lib/gssapi/libgssapi-exports.def +++ b/lib/gssapi/libgssapi-exports.def @@ -168,6 +168,7 @@ EXPORTS __gss_krb5_mechanism_oid_desc DATA __gss_ntlm_mechanism_oid_desc DATA __gss_spnego_mechanism_oid_desc DATA + __gss_sanon_x25519_mechanism_oid_desc DATA __gss_c_ma_mech_concrete_oid_desc DATA __gss_c_ma_mech_pseudo_oid_desc DATA __gss_c_ma_mech_composite_oid_desc DATA diff --git a/lib/gssapi/mech/gss_mech_switch.c b/lib/gssapi/mech/gss_mech_switch.c index 9085e962f..9e4c96dec 100644 --- a/lib/gssapi/mech/gss_mech_switch.c +++ b/lib/gssapi/mech/gss_mech_switch.c @@ -296,10 +296,8 @@ _gss_load_mech(void) #ifdef HAVE_DLOPEN fp = fopen(conf ? conf : _PATH_GSS_MECH, "r"); - if (!fp) { - HEIMDAL_MUTEX_unlock(&_gss_mech_mutex); - return; - } + if (!fp) + goto out; rk_cloexec_file(fp); while (fgets(buf, sizeof(buf), fp)) { @@ -460,6 +458,9 @@ _gss_load_mech(void) } fclose(fp); #endif + +out: + add_builtin(__gss_sanon_initialize()); HEIMDAL_MUTEX_unlock(&_gss_mech_mutex); } diff --git a/lib/gssapi/mech/gss_oid.c b/lib/gssapi/mech/gss_oid.c index 69ff9868c..10ec22dbe 100644 --- a/lib/gssapi/mech/gss_oid.c +++ b/lib/gssapi/mech/gss_oid.c @@ -154,6 +154,9 @@ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_reset_crypto_oid_desc = { 11, rk_U /* GSS_NEGOEX_MECHANISM - 1.3.6.1.4.1.311.2.2.30 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_negoex_mechanism_oid_desc = { 10, rk_UNCONST("\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x1e") }; +/* GSS_SANON_X25519_MECHANISM - 1.3.6.1.4.1.5322.26.1.110 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_sanon_x25519_mechanism_oid_desc = { 10, rk_UNCONST("\x2b\x06\x01\x04\x01\xa9\x4a\x1a\x01\x6e") }; + /* GSS_C_MA_MECH_CONCRETE - 1.3.6.1.5.5.13.1 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_mech_concrete_oid_desc = { 7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0d\x01") }; @@ -276,6 +279,7 @@ struct _gss_oid_name_table _gss_ont_ma[] = { struct _gss_oid_name_table _gss_ont_mech[] = { { GSS_KRB5_MECHANISM, "GSS_KRB5_MECHANISM", "Kerberos 5", "Heimdal Kerberos 5 mechanism" }, { GSS_NTLM_MECHANISM, "GSS_NTLM_MECHANISM", "NTLM", "Heimdal NTLM mechanism" }, + { GSS_SANON_X25519_MECHANISM, "GSS_SANON_X25519_MECHANISM", "SAnon-X25519", "Heimdal Simple Anonymous (X25519) mechanism" }, { GSS_SPNEGO_MECHANISM, "GSS_SPNEGO_MECHANISM", "SPNEGO", "Heimdal SPNEGO mechanism" }, { NULL, NULL, NULL, NULL } }; @@ -332,6 +336,7 @@ gss_OID _gss_ot_internal[] = { &__gss_c_inq_peer_has_buggy_spnego_oid_desc, &__gss_c_ntlm_reset_crypto_oid_desc, &__gss_negoex_mechanism_oid_desc, + &__gss_sanon_x25519_mechanism_oid_desc, &__gss_c_ma_mech_concrete_oid_desc, &__gss_c_ma_mech_pseudo_oid_desc, &__gss_c_ma_mech_composite_oid_desc, diff --git a/lib/gssapi/oid.txt b/lib/gssapi/oid.txt index 93bcf443a..12e167f39 100644 --- a/lib/gssapi/oid.txt +++ b/lib/gssapi/oid.txt @@ -70,7 +70,7 @@ oid base GSS_SPNEGO_MECHANISM 1.3.6.1.5.5.2 oid base GSS_C_INQ_PEER_HAS_BUGGY_SPNEGO 1.3.6.1.4.1.5322.19.6 oid base GSS_C_NTLM_RESET_CRYPTO 1.3.6.1.4.1.7165.655.1.3 oid base GSS_NEGOEX_MECHANISM 1.3.6.1.4.1.311.2.2.30 - +oid base GSS_SANON_X25519_MECHANISM 1.3.6.1.4.1.5322.26.1.110 #/* # * OID mappings with name and short description and and slightly longer description @@ -79,6 +79,7 @@ oid base GSS_NEGOEX_MECHANISM 1.3.6.1.4.1.311.2.2.30 desc mech GSS_KRB5_MECHANISM "Kerberos 5" "Heimdal Kerberos 5 mechanism" desc mech GSS_NTLM_MECHANISM "NTLM" "Heimdal NTLM mechanism" desc mech GSS_SPNEGO_MECHANISM "SPNEGO" "Heimdal SPNEGO mechanism" +desc mech GSS_SANON_X25519_MECHANISM "SAnon-X25519" "Heimdal Simple Anonymous (X25519) mechanism" desc ma GSS_C_MA_MECH_NAME "GSS mech name" "The name of the GSS-API mechanism" desc ma GSS_C_MA_SASL_MECH_NAME "SASL mechanism name" "The name of the SASL mechanism" diff --git a/lib/gssapi/sanon/accept_sec_context.c b/lib/gssapi/sanon/accept_sec_context.c new file mode 100644 index 000000000..cd0b7fd44 --- /dev/null +++ b/lib/gssapi/sanon/accept_sec_context.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_accept_sec_context(OM_uint32 *minor, + gss_ctx_id_t *context_handle, + gss_const_cred_id_t verifier_cred_handle, + const gss_buffer_t input_token, + const gss_channel_bindings_t input_chan_bindings, + gss_name_t *src_name, + gss_OID *mech_type, + gss_buffer_t output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec, + gss_cred_id_t *delegated_cred_handle) +{ + static gss_buffer_desc empty = GSS_C_EMPTY_BUFFER; + OM_uint32 major, tmp; + sanon_ctx sc = (sanon_ctx)*context_handle; + gss_buffer_desc mech_input_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc hok_mic = GSS_C_EMPTY_BUFFER; + OM_uint32 flags; + gss_buffer_desc session_key = GSS_C_EMPTY_BUFFER; + + if (output_token == GSS_C_NO_BUFFER) { + *minor = EINVAL; + major = GSS_S_FAILURE; + goto out; + } + + _mg_buffer_zero(output_token); + + if (input_token == GSS_C_NO_BUFFER) { + major = GSS_S_DEFECTIVE_TOKEN; + goto out; + } else if (sc != NULL && sc->rfc4121 != GSS_C_NO_CONTEXT) { + major = GSS_S_BAD_STATUS; + goto out; + } + + major = gss_decapsulate_token(input_token, + GSS_SANON_X25519_MECHANISM, + &mech_input_token); + if (major != GSS_S_COMPLETE) + goto out; + + if (sc == NULL) { + sc = calloc(1, sizeof(*sc)); + if (sc == NULL) { + *minor = ENOMEM; + major = GSS_S_FAILURE; + goto out; + } + } + + /* compute public and secret keys */ + major = _gss_sanon_curve25519_base(minor, sc); + if (major != GSS_S_COMPLETE) + goto out; + + /* compute shared secret */ + major = _gss_sanon_curve25519(minor, sc, &mech_input_token, + input_chan_bindings, &session_key); + if (major != GSS_S_COMPLETE) + goto out; + + flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | + GSS_C_INTEG_FLAG | GSS_C_ANON_FLAG | GSS_C_TRANS_FLAG; + flags |= sanon_to_rfc4757_flags(sc->flags); + + major = _gss_sanon_import_rfc4121_context(minor, sc, flags, &session_key); + if (major != GSS_S_COMPLETE) + goto out; + + major = _gss_sanon_get_mic(minor, (gss_const_ctx_id_t)sc, + GSS_C_QOP_DEFAULT, &empty, &hok_mic); + if (major != GSS_S_COMPLETE) + goto out; + + output_token->length = sizeof(sc->pk) + hok_mic.length; + output_token->value = malloc(output_token->length); + if (output_token->value == NULL) { + output_token->length = 0; + *minor = ENOMEM; + major = GSS_S_FAILURE; + goto out; + } + + memcpy(output_token->value, sc->pk, sizeof(sc->pk)); + memcpy((uint8_t *)output_token->value + sizeof(sc->pk), hok_mic.value, hok_mic.length); + + major = GSS_S_COMPLETE; + + *context_handle = (gss_ctx_id_t)sc; + + if (src_name) + *src_name = _gss_sanon_anonymous_identity; + if (ret_flags) + *ret_flags = flags; + if (time_rec) + *time_rec = GSS_C_INDEFINITE; + +out: + if (mech_type) + *mech_type = GSS_SANON_X25519_MECHANISM; + if (delegated_cred_handle) + *delegated_cred_handle = GSS_C_NO_CREDENTIAL; + if (GSS_ERROR(major)) { + _gss_sanon_delete_sec_context(&tmp, (gss_ctx_id_t *)&sc, GSS_C_NO_BUFFER); + *context_handle = GSS_C_NO_CONTEXT; + } + gss_release_buffer(&tmp, &mech_input_token); + gss_release_buffer(&tmp, &hok_mic); + _gss_secure_release_buffer(&tmp, &session_key); + + return major; +} diff --git a/lib/gssapi/sanon/acquire_cred.c b/lib/gssapi/sanon/acquire_cred.c new file mode 100644 index 000000000..7aedd3e26 --- /dev/null +++ b/lib/gssapi/sanon/acquire_cred.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +/* SAnon credential handles are aliases of their underyling name */ + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_acquire_cred_from(OM_uint32 *minor, + gss_const_name_t desired_name, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_const_key_value_set_t cred_stor, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec) +{ + *minor = 0; + + if (desired_name == GSS_C_NO_NAME || + desired_name == _gss_sanon_anonymous_identity) + *output_cred_handle = _gss_sanon_anonymous_cred; + else + *output_cred_handle = _gss_sanon_non_anonymous_cred; + + if (time_rec) + *time_rec = GSS_C_INDEFINITE; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/add_cred.c b/lib/gssapi/sanon/add_cred.c new file mode 100644 index 000000000..f1dfeba13 --- /dev/null +++ b/lib/gssapi/sanon/add_cred.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_add_cred_from(OM_uint32 *minor, + gss_cred_id_t input_cred_handle, + gss_const_name_t desired_name, + const gss_OID desired_mech, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_const_key_value_set_t cred_store, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec) +{ + *minor = 0; + + if (output_cred_handle != NULL) { + if (desired_name == GSS_C_NO_NAME || + desired_name == _gss_sanon_anonymous_identity) + *output_cred_handle = _gss_sanon_anonymous_cred; + else + *output_cred_handle = _gss_sanon_non_anonymous_cred; + } + + if (initiator_time_rec) + *initiator_time_rec = GSS_C_INDEFINITE; + if (acceptor_time_rec) + *acceptor_time_rec = GSS_C_INDEFINITE; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/canonicalize_name.c b/lib/gssapi/sanon/canonicalize_name.c new file mode 100644 index 000000000..fa1ade0ce --- /dev/null +++ b/lib/gssapi/sanon/canonicalize_name.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_canonicalize_name(OM_uint32 *minor, + gss_const_name_t src_name, + const gss_OID mech_type, + gss_name_t *dest_name) +{ + *minor = 0; + + if (src_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + *dest_name = (gss_name_t)src_name; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/compare_name.c b/lib/gssapi/sanon/compare_name.c new file mode 100644 index 000000000..85b13b2d4 --- /dev/null +++ b/lib/gssapi/sanon/compare_name.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_compare_name(OM_uint32 *minor, + gss_const_name_t name1, + gss_const_name_t name2, + int *name_equal) +{ + *minor = 0; + + /* + * RFC 2743 Section 2.4.3: + * If either name presented to GSS_Compare_name() denotes + * an anonymous principal, GSS_Compare_name() shall indicate + * FALSE + * + * We also have to apply the same logic to non-anonymous + * names as we erase their contents. + */ + *name_equal = FALSE; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/context_time.c b/lib/gssapi/sanon/context_time.c new file mode 100644 index 000000000..338f3acfd --- /dev/null +++ b/lib/gssapi/sanon/context_time.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_context_time(OM_uint32 *minor, + gss_const_ctx_id_t context_handle, + OM_uint32 *time_rec) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + *minor = 0; + *time_rec = GSS_C_INDEFINITE; + + if (sc == NULL) + return GSS_S_NO_CONTEXT; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/crypto.c b/lib/gssapi/sanon/crypto.c new file mode 100644 index 000000000..2a4d8e874 --- /dev/null +++ b/lib/gssapi/sanon/crypto.c @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_wrap(OM_uint32 *minor, + gss_const_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + const gss_buffer_t input_message_buffer, + int *conf_state, + gss_buffer_t output_message_buffer) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + if (sc->rfc4121 == GSS_C_NO_CONTEXT) { + *minor = GSS_KRB5_S_KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + return gss_wrap(minor, sc->rfc4121, + conf_req_flag, qop_req, + input_message_buffer, conf_state, + output_message_buffer); +} + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_wrap_size_limit(OM_uint32 *minor, + gss_const_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + OM_uint32 req_output_size, + OM_uint32 *max_input_size) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + if (sc->rfc4121 == GSS_C_NO_CONTEXT) { + *minor = GSS_KRB5_S_KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + return gss_wrap_size_limit(minor, sc->rfc4121, + conf_req_flag, qop_req, + req_output_size, max_input_size); +} + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_wrap_iov(OM_uint32 *minor, + gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + if (sc->rfc4121 == GSS_C_NO_CONTEXT) { + *minor = GSS_KRB5_S_KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + return gss_wrap_iov(minor, sc->rfc4121, + conf_req_flag, qop_req, + conf_state, iov, iov_count); +} + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_wrap_iov_length(OM_uint32 *minor, + gss_ctx_id_t context_handle, + int conf_req_flag, + gss_qop_t qop_req, + int *conf_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + if (sc->rfc4121 == GSS_C_NO_CONTEXT) { + *minor = GSS_KRB5_S_KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + return gss_wrap_iov_length(minor, sc->rfc4121, + conf_req_flag, qop_req, + conf_state, iov, iov_count); +} + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_unwrap(OM_uint32 *minor, + gss_const_ctx_id_t context_handle, + const gss_buffer_t input_message_buffer, + gss_buffer_t output_message_buffer, + int *conf_state, + gss_qop_t * qop_state) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + if (sc->rfc4121 == GSS_C_NO_CONTEXT) { + *minor = GSS_KRB5_S_KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + return gss_unwrap(minor, sc->rfc4121, + input_message_buffer, output_message_buffer, + conf_state, qop_state); +} + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_unwrap_iov(OM_uint32 *minor, + gss_ctx_id_t context_handle, + int *conf_state, + gss_qop_t *qop_state, + gss_iov_buffer_desc *iov, + int iov_count) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + if (sc->rfc4121 == GSS_C_NO_CONTEXT) { + *minor = GSS_KRB5_S_KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + return gss_unwrap_iov(minor, sc->rfc4121, + conf_state, qop_state, + iov, iov_count); +} + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_get_mic(OM_uint32 *minor, + gss_const_ctx_id_t context_handle, + gss_qop_t qop_req, + const gss_buffer_t message_buffer, + gss_buffer_t message_token) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + if (sc->rfc4121 == GSS_C_NO_CONTEXT) { + *minor = GSS_KRB5_S_KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + return gss_get_mic(minor, sc->rfc4121, + qop_req, message_buffer, + message_token); +} + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_verify_mic(OM_uint32 *minor, + gss_const_ctx_id_t context_handle, + const gss_buffer_t message_buffer, + const gss_buffer_t token_buffer, + gss_qop_t *qop_state) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + if (sc->rfc4121 == GSS_C_NO_CONTEXT) { + *minor = GSS_KRB5_S_KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + return gss_verify_mic(minor, sc->rfc4121, + message_buffer, token_buffer, + qop_state); +} + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_pseudo_random(OM_uint32 *minor, + gss_ctx_id_t context_handle, + int prf_key, + const gss_buffer_t prf_in, + ssize_t desired_output_len, + gss_buffer_t prf_out) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + if (sc->rfc4121 == GSS_C_NO_CONTEXT) { + *minor = GSS_KRB5_S_KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } + + return gss_pseudo_random(minor, sc->rfc4121, + prf_key, prf_in, desired_output_len, + prf_out); +} + +/* + * Generate a curve25519 secret and public key + */ + +OM_uint32 +_gss_sanon_curve25519_base(OM_uint32 *minor, sanon_ctx sc) +{ + krb5_generate_random_block(sc->sk, crypto_scalarmult_curve25519_BYTES); + + if (crypto_scalarmult_curve25519_base(sc->pk, sc->sk) != 0) { + *minor = EINVAL; + return GSS_S_FAILURE; + } + + return GSS_S_COMPLETE; +} + +/* + * Derive the context session key using SP800-108 KDF in HMAC mode + * and the public keys and channel binding data. + */ + +OM_uint32 +_gss_sanon_curve25519(OM_uint32 *minor, + sanon_ctx sc, + gss_buffer_t pk, + const gss_channel_bindings_t input_chan_bindings, + gss_buffer_t session_key) +{ + uint8_t shared[crypto_scalarmult_curve25519_BYTES], *p; + krb5_error_code ret; + krb5_context context; + krb5_data kdf_K1, kdf_label, kdf_context, keydata; + + _mg_buffer_zero(session_key); + + if (pk == GSS_C_NO_BUFFER || pk->length != crypto_scalarmult_curve25519_BYTES) + return GSS_S_DEFECTIVE_TOKEN; + + if (crypto_scalarmult_curve25519(shared, sc->sk, pk->value) != 0) + return GSS_S_FAILURE; + + ret = krb5_init_context(&context); + if (ret != 0) { + *minor = ret; + return GSS_S_FAILURE; + } + + kdf_K1.data = shared; + kdf_K1.length = sizeof(shared); + + kdf_label.data = "sanon-x25519"; + kdf_label.length = sizeof("sanon-x25519") - 1; + + ret = krb5_data_alloc(&kdf_context, + 2 * crypto_scalarmult_curve25519_BYTES + + (input_chan_bindings ? input_chan_bindings->application_data.length : 0)); + if (ret != 0) { + krb5_free_context(context); + *minor = ret; + return GSS_S_FAILURE; + } + + p = kdf_context.data; + + if (sc->flags & SANON_FLAG_INITIATOR) { + memcpy(p, sc->pk, sizeof(sc->pk)); + memcpy(&p[pk->length], pk->value, pk->length); + } else { + memcpy(p, pk->value, pk->length); + memcpy(&p[sizeof(sc->pk)], sc->pk, sizeof(sc->pk)); + } + + if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS && + input_chan_bindings->application_data.value != NULL) { + memcpy(&p[2 * crypto_scalarmult_curve25519_BYTES], + input_chan_bindings->application_data.value, + input_chan_bindings->application_data.length); + } + + ret = krb5_data_alloc(&keydata, 16); + if (ret == 0) { + ret = _krb5_SP800_108_HMAC_KDF(context, &kdf_K1, &kdf_label, + &kdf_context, EVP_sha256(), &keydata); + + session_key->length = keydata.length; + session_key->value = keydata.data; + } else { + krb5_data_free(&keydata); + } + + memset_s(kdf_context.data, kdf_context.length, 0, kdf_context.length); + krb5_data_free(&kdf_context); + + memset_s(shared, sizeof(shared), 0, sizeof(shared)); + + krb5_free_context(context); + + *minor = ret; + return ret != 0 ? GSS_S_FAILURE : GSS_S_COMPLETE; +} + +OM_uint32 +_gss_sanon_import_rfc4121_context(OM_uint32 *minor, + sanon_ctx sc, + OM_uint32 flags, + gss_const_buffer_t session_key) +{ + return _gss_mg_import_rfc4121_context(minor, + !!(sc->flags & SANON_FLAG_INITIATOR), + flags, + KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128, + session_key, + &sc->rfc4121); +} + diff --git a/lib/gssapi/sanon/delete_sec_context.c b/lib/gssapi/sanon/delete_sec_context.c new file mode 100644 index 000000000..fdb8a8555 --- /dev/null +++ b/lib/gssapi/sanon/delete_sec_context.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_delete_sec_context(OM_uint32 *minor, + gss_ctx_id_t *context_handle, + gss_buffer_t output_token) +{ + sanon_ctx sc; + + *minor = 0; + + if (output_token != GSS_C_NO_BUFFER) { + output_token->length = 0; + output_token->value = NULL; + } + + if (*context_handle == GSS_C_NO_CONTEXT) + return GSS_S_COMPLETE; + + sc = (sanon_ctx)*context_handle; + + *context_handle = GSS_C_NO_CONTEXT; + + gss_delete_sec_context(minor, &sc->rfc4121, GSS_C_NO_BUFFER); + + memset_s(sc, sizeof(*sc), 0, sizeof(*sc)); + free(sc); + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/display_name.c b/lib/gssapi/sanon/display_name.c new file mode 100644 index 000000000..1bd55f3d6 --- /dev/null +++ b/lib/gssapi/sanon/display_name.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_display_name(OM_uint32 *minor, + gss_const_name_t input_name, + gss_buffer_t output_name_buffer, + gss_OID *output_name_type) +{ + *minor = 0; + + if (input_name != _gss_sanon_anonymous_identity) + return GSS_S_BAD_NAME; + + if (output_name_type) + *output_name_type = GSS_C_NT_ANONYMOUS; + + return _gss_copy_buffer(minor, _gss_sanon_wellknown_user_name, + output_name_buffer); +} diff --git a/lib/gssapi/sanon/display_status.c b/lib/gssapi/sanon/display_status.c new file mode 100644 index 000000000..4e039c6bc --- /dev/null +++ b/lib/gssapi/sanon/display_status.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1998 - 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_display_status(OM_uint32 *minor, + OM_uint32 status_value, + int status_type, + const gss_OID mech_type, + OM_uint32 *message_context, + gss_buffer_t status_string) +{ + _mg_buffer_zero(status_string); + + if (gss_oid_equal(mech_type, GSS_C_NO_OID) == 0 && + gss_oid_equal(mech_type, GSS_SANON_X25519_MECHANISM) == 0) { + *minor = 0; + return GSS_S_BAD_MECH; + } + + if (status_type == GSS_C_MECH_CODE) { + return gss_display_status(minor, status_value, + GSS_C_MECH_CODE, GSS_KRB5_MECHANISM, + message_context, status_string); + } else { + *minor = EINVAL; + return GSS_S_BAD_STATUS; + } +} diff --git a/lib/gssapi/sanon/duplicate_cred.c b/lib/gssapi/sanon/duplicate_cred.c new file mode 100644 index 000000000..8c5c5d863 --- /dev/null +++ b/lib/gssapi/sanon/duplicate_cred.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_duplicate_cred(OM_uint32 *minor, + gss_const_cred_id_t input_cred_handle, + gss_cred_id_t *output_cred_handle) +{ + *minor = 0; + *output_cred_handle = (gss_cred_id_t)input_cred_handle; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/duplicate_name.c b/lib/gssapi/sanon/duplicate_name.c new file mode 100644 index 000000000..698e83dc8 --- /dev/null +++ b/lib/gssapi/sanon/duplicate_name.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_duplicate_name(OM_uint32 *minor, + gss_const_name_t src_name, + gss_name_t *dest_name) +{ + *minor = 0; + *dest_name = (gss_name_t)src_name; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/export_cred.c b/lib/gssapi/sanon/export_cred.c new file mode 100644 index 000000000..06c2458f7 --- /dev/null +++ b/lib/gssapi/sanon/export_cred.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_export_cred(OM_uint32 *minor, + gss_cred_id_t input_cred, + gss_buffer_t token) +{ + return _gss_sanon_export_name(minor, (gss_name_t)input_cred, token); +} diff --git a/lib/gssapi/sanon/export_name.c b/lib/gssapi/sanon/export_name.c new file mode 100644 index 000000000..474c58cc1 --- /dev/null +++ b/lib/gssapi/sanon/export_name.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_export_name(OM_uint32 *minor, + gss_const_name_t input_name, + gss_buffer_t exported_name) +{ + uint8_t is_anonymous; + + *minor = 0; + + if (input_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + is_anonymous = input_name == _gss_sanon_anonymous_identity; + if (!is_anonymous) + return GSS_S_BAD_NAME; + + return gss_mg_export_name(minor, GSS_SANON_X25519_MECHANISM, + &is_anonymous, 1, exported_name); +} diff --git a/lib/gssapi/sanon/export_sec_context.c b/lib/gssapi/sanon/export_sec_context.c new file mode 100644 index 000000000..f788dae88 --- /dev/null +++ b/lib/gssapi/sanon/export_sec_context.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_export_sec_context(OM_uint32 *minor, + gss_ctx_id_t *context_handle, + gss_buffer_t interprocess_token) +{ + OM_uint32 major; + const sanon_ctx sc = (sanon_ctx)*context_handle; + + if (sc->rfc4121 == GSS_C_NO_CONTEXT) { + _mg_buffer_zero(interprocess_token); + *minor = 0; + return GSS_S_UNAVAILABLE; + } + + major = gss_export_sec_context(minor, &sc->rfc4121, interprocess_token); + if (major == GSS_S_COMPLETE) { + _gss_sanon_delete_sec_context(minor, context_handle, + GSS_C_NO_BUFFER); + } + return major; +} diff --git a/lib/gssapi/sanon/external.c b/lib/gssapi/sanon/external.c new file mode 100644 index 000000000..fa100fe7a --- /dev/null +++ b/lib/gssapi/sanon/external.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2006-2020 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sanon_locl.h" + +static uint8_t anonymous_identity; +gss_name_t +_gss_sanon_anonymous_identity = (gss_name_t)&anonymous_identity; +gss_cred_id_t +_gss_sanon_anonymous_cred = (gss_cred_id_t)&anonymous_identity; + +static uint8_t non_anonymous_identity; +gss_name_t +_gss_sanon_non_anonymous_identity = (gss_name_t)&non_anonymous_identity; +gss_cred_id_t +_gss_sanon_non_anonymous_cred = (gss_cred_id_t)&non_anonymous_identity; + +static gss_buffer_desc wellknown_user_name = { + SANON_WELLKNOWN_USER_NAME_LEN, + SANON_WELLKNOWN_USER_NAME +}; +gss_buffer_t +_gss_sanon_wellknown_user_name = &wellknown_user_name; + +static gss_buffer_desc wellknown_service_name = { + SANON_WELLKNOWN_SERVICE_NAME_LEN, + SANON_WELLKNOWN_SERVICE_NAME +}; +gss_buffer_t +_gss_sanon_wellknown_service_name = &wellknown_service_name; + +static gss_mo_desc sanon_mo[] = { + { + GSS_C_MA_MECH_NAME, + GSS_MO_MA, + "Mechanism name", + rk_UNCONST("SANON-X25519"), + _gss_mo_get_ctx_as_string, + NULL + }, + { + GSS_C_MA_MECH_DESCRIPTION, + GSS_MO_MA, + "Mechanism description", + rk_UNCONST("Heimdal Simple Anonymous (X25519) Mechanism"), + _gss_mo_get_ctx_as_string, + NULL + }, + { + GSS_C_MA_MECH_CONCRETE, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_ITOK_FRAMED, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_AUTH_INIT_ANON, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_AUTH_TARG_ANON, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_INTEG_PROT, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_CONF_PROT, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_MIC, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_WRAP, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_REPLAY_DET, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_OOS_DET, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_CBINDINGS, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_PFS, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_CTX_TRANS, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + }, + { + GSS_C_MA_NEGOEX_AND_SPNEGO, + GSS_MO_MA, + NULL, + NULL, + NULL, + NULL + } +}; + +static gssapi_mech_interface_desc sanon_mech = { + GMI_VERSION, + "sanon-x25519", + { 10, rk_UNCONST("\x2b\x06\x01\x04\x01\xa9\x4a\x1a\x01\x6e") }, + 0, + NULL, + _gss_sanon_release_cred, + _gss_sanon_init_sec_context, + _gss_sanon_accept_sec_context, + _gss_sanon_process_context_token, + _gss_sanon_delete_sec_context, + _gss_sanon_context_time, + _gss_sanon_get_mic, + _gss_sanon_verify_mic, + _gss_sanon_wrap, + _gss_sanon_unwrap, + _gss_sanon_display_status, + NULL, /* gm_indicate_mechs */ + _gss_sanon_compare_name, + _gss_sanon_display_name, + _gss_sanon_import_name, + _gss_sanon_export_name, + _gss_sanon_release_name, + _gss_sanon_inquire_cred, + _gss_sanon_inquire_context, + _gss_sanon_wrap_size_limit, + NULL, /* gm_add_cred */ + _gss_sanon_inquire_cred_by_mech, + _gss_sanon_export_sec_context, + _gss_sanon_import_sec_context, + _gss_sanon_inquire_names_for_mech, + _gss_sanon_inquire_mechs_for_name, + _gss_sanon_canonicalize_name, + _gss_sanon_duplicate_name, + _gss_sanon_inquire_sec_context_by_oid, + NULL, /* gm_inquire_cred_by_oid */ + NULL, /* gm_set_sec_context_option */ + NULL, /* gm_set_cred_option */ + _gss_sanon_pseudo_random, + _gss_sanon_wrap_iov, + _gss_sanon_unwrap_iov, + _gss_sanon_wrap_iov_length, + NULL, /* gm_store_cred */ + _gss_sanon_export_cred, + _gss_sanon_import_cred, + _gss_sanon_acquire_cred_from, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + sanon_mo, + sizeof(sanon_mo) / sizeof(sanon_mo[0]), + NULL, /* gm_localname */ + NULL, /* gm_authorize_localname */ + NULL, /* gm_display_name_ext */ + NULL, /* gm_inquire_name */ + NULL, /* gm_get_name_attribute */ + NULL, /* gm_set_name_attribute */ + NULL, /* gm_delete_name_attribute */ + NULL, /* gm_export_name_composite */ + _gss_sanon_duplicate_cred, + _gss_sanon_add_cred_from, + NULL, /* gm_store_cred_into */ + _gssspi_sanon_query_mechanism_info, + _gssspi_sanon_query_meta_data, + _gssspi_sanon_exchange_meta_data, + NULL, /* gm_store_cred_into2 */ + NULL, /* gm_compat */ +}; + +gssapi_mech_interface +__gss_sanon_initialize(void) +{ + return &sanon_mech; +} diff --git a/lib/gssapi/sanon/import_cred.c b/lib/gssapi/sanon/import_cred.c new file mode 100644 index 000000000..4266ef147 --- /dev/null +++ b/lib/gssapi/sanon/import_cred.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_import_cred(OM_uint32 *minor, + gss_buffer_t token, + gss_cred_id_t *cred_handle) +{ + return _gss_sanon_import_name(minor, token, + GSS_C_NT_EXPORT_NAME, + (gss_name_t *)cred_handle); +} diff --git a/lib/gssapi/sanon/import_name.c b/lib/gssapi/sanon/import_name.c new file mode 100644 index 000000000..189308d96 --- /dev/null +++ b/lib/gssapi/sanon/import_name.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +static int +is_anonymous_identity_p(gss_buffer_t name_string, gss_OID name_type) +{ + if (gss_oid_equal(name_type, GSS_C_NT_ANONYMOUS)) + return TRUE; + else if ((gss_oid_equal(name_type, GSS_C_NT_USER_NAME) || + gss_oid_equal(name_type, GSS_KRB5_NT_PRINCIPAL_NAME)) && + buffer_equal_p(name_string, _gss_sanon_wellknown_user_name)) + return TRUE; + else if (gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE) && + buffer_equal_p(name_string, _gss_sanon_wellknown_service_name)) + return TRUE; + + return FALSE; +} + +static krb5_error_code +storage_ret_der_oid(krb5_storage *sp, gss_OID_desc *oid) +{ + krb5_error_code ret; + uint16_t der_oid_len; + uint8_t oid_len, tag; + + oid->length = 0; + oid->elements = NULL; + + ret = krb5_ret_uint16(sp, &der_oid_len); + if (ret != 0) + return ret; + + ret = krb5_ret_uint8(sp, &tag); + if (tag != 0x06) + return EINVAL; + + ret = krb5_ret_uint8(sp, &oid_len); + if (ret != 0) + return ret; + + if (der_oid_len != 2 + oid_len) + return EINVAL; + + oid->elements = malloc(oid_len); + if (oid->elements == NULL) + return ENOMEM; + + if (krb5_storage_read(sp, oid->elements, oid_len) != oid_len) { + free(oid->elements); + oid->elements = NULL; + oid->length = 0; + return EINVAL; + } + + oid->length = oid_len; + + return 0; +} + +static OM_uint32 +import_export_name(OM_uint32 *minor, + const gss_buffer_t input_name_buffer, + gss_name_t *output_name) +{ + OM_uint32 major; + krb5_error_code ret; + krb5_storage *sp; + uint32_t name_len = 0; + uint16_t tok_id; + gss_OID_desc oid_buf = { 0, NULL }; + uint8_t is_anonymous; + + sp = krb5_storage_from_readonly_mem(input_name_buffer->value, + input_name_buffer->length); + if (sp == NULL) { + *minor = ENOMEM; + return GSS_S_FAILURE; + } + + krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); + + major = GSS_S_BAD_NAME; + *minor = 0; + + ret = krb5_ret_uint16(sp, &tok_id); + if (ret == 0 && tok_id != 0x0401) + ret = EINVAL; + if (ret == 0) + ret = storage_ret_der_oid(sp, &oid_buf); + if (ret == 0) { + if (!gss_oid_equal(&oid_buf, GSS_SANON_X25519_MECHANISM)) + ret = EINVAL; + free(oid_buf.elements); + } + if (ret == 0) + ret = krb5_ret_uint32(sp, &name_len); + if (name_len != 1) + ret = EINVAL; + ret = krb5_ret_uint8(sp, &is_anonymous); + if (ret == 0) { + if (is_anonymous == 1) { + *output_name = _gss_sanon_anonymous_identity; + major = GSS_S_COMPLETE; + } else { + major = GSS_S_BAD_NAME; + } + } + + krb5_storage_free(sp); + + if (*minor == 0) + *minor = ret; + + return major; +} + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_import_name(OM_uint32 *minor, + const gss_buffer_t input_name_buffer, + const gss_OID input_name_type, + gss_name_t *output_name) +{ + heim_assert(input_name_type != GSS_C_NO_OID, + "Mechglue passed null OID to _gss_sanon_import_name"); + + if (gss_oid_equal(input_name_type, GSS_C_NT_EXPORT_NAME)) + return import_export_name(minor, input_name_buffer, output_name); + + *minor = 0; + *output_name = + is_anonymous_identity_p(input_name_buffer, input_name_type) ? + _gss_sanon_anonymous_identity : _gss_sanon_non_anonymous_identity; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/import_sec_context.c b/lib/gssapi/sanon/import_sec_context.c new file mode 100644 index 000000000..9aa682a34 --- /dev/null +++ b/lib/gssapi/sanon/import_sec_context.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_import_sec_context(OM_uint32 *minor, + const gss_buffer_t interprocess_token, + gss_ctx_id_t *context_handle) +{ + OM_uint32 major = GSS_S_FAILURE; + sanon_ctx sc; + + *minor = ENOMEM; + *context_handle = GSS_C_NO_CONTEXT; + + if ((sc = calloc(1, sizeof(*sc))) && + (major = gss_import_sec_context(minor, + interprocess_token, + &sc->rfc4121)) == GSS_S_COMPLETE) { + *context_handle = (gss_ctx_id_t)sc; + sc = NULL; + } + + free(sc); + return major; +} diff --git a/lib/gssapi/sanon/init_sec_context.c b/lib/gssapi/sanon/init_sec_context.c new file mode 100644 index 000000000..08f630e54 --- /dev/null +++ b/lib/gssapi/sanon/init_sec_context.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +int +_gss_sanon_available_p(gss_const_cred_id_t claimant_cred_handle, + gss_const_name_t target_name, + OM_uint32 req_flags) +{ + OM_uint32 minor; + gss_name_t initiator_name = GSS_C_NO_NAME; + int available; + + if (claimant_cred_handle != GSS_C_NO_CREDENTIAL) { + _gss_sanon_inquire_cred(&minor, claimant_cred_handle, + &initiator_name, NULL, NULL, NULL); + heim_assert(initiator_name != GSS_C_NO_NAME, + "Invalid null SAnon initiator name"); + } + + /* + * SAnon is available if one of the following is true: + * + * The caller set anon_req_flag (GSS_C_ANON_FLAG) + * The claimant_cred_handle identity is anonymous + * The claimant_cred_handle is the default credential + * and target_name is anonymous + */ + if (req_flags & GSS_C_ANON_FLAG) + available = TRUE; + else if (initiator_name == _gss_sanon_anonymous_identity) + available = TRUE; + else if (claimant_cred_handle == GSS_C_NO_CREDENTIAL && + target_name == _gss_sanon_anonymous_identity) + available = TRUE; + else + available = FALSE; + + _gss_sanon_release_name(&minor, &initiator_name); + return available; +} + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_init_sec_context(OM_uint32 *minor, + gss_const_cred_id_t cred_handle, + gss_ctx_id_t *context_handle, + gss_const_name_t target_name, + const gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + const gss_channel_bindings_t input_chan_bindings, + const gss_buffer_t input_token, + gss_OID *actual_mech_type, + gss_buffer_t output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec) +{ + gss_buffer_desc mech_token = GSS_C_EMPTY_BUFFER; + OM_uint32 major, tmp; + sanon_ctx sc = (sanon_ctx)*context_handle; + OM_uint32 flags = 0; + gss_buffer_desc session_key = GSS_C_EMPTY_BUFFER; + + *minor = 0; + _mg_buffer_zero(output_token); + + if (!_gss_sanon_available_p(cred_handle, target_name, req_flags)) { + major = GSS_S_UNAVAILABLE; + goto out; + } + + flags |= GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | + GSS_C_INTEG_FLAG | GSS_C_DCE_STYLE | GSS_C_IDENTIFY_FLAG | + GSS_C_EXTENDED_ERROR_FLAG; /* supported flags */ + flags &= req_flags; + flags |= GSS_C_ANON_FLAG; /* always set this flag */ + + if (sc == NULL) { + if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) { + major = GSS_S_DEFECTIVE_TOKEN; + goto out; + } + + sc = calloc(1, sizeof(*sc)); + if (sc == NULL) { + *minor = ENOMEM; + major = GSS_S_FAILURE; + goto out; + } + + sc->flags = SANON_FLAG_INITIATOR | rfc4757_to_sanon_flags(req_flags); + + /* compute public and secret keys */ + major = _gss_sanon_curve25519_base(minor, sc); + if (major != GSS_S_COMPLETE) + goto out; + + mech_token.length = sizeof(sc->pk); + mech_token.value = sc->pk; + + /* send public key to acceptor */ + major = gss_encapsulate_token(&mech_token, + GSS_SANON_X25519_MECHANISM, + output_token); + if (major != GSS_S_COMPLETE) + goto out; + + *context_handle = (gss_ctx_id_t)sc; + major = GSS_S_CONTINUE_NEEDED; + } else { + static gss_buffer_desc empty = GSS_C_EMPTY_BUFFER; + gss_buffer_desc pk, hok_mic; + + if (input_token == GSS_C_NO_BUFFER || + input_token->length < crypto_scalarmult_curve25519_BYTES) { + major = GSS_S_DEFECTIVE_TOKEN; + goto out; + } else if (sc->rfc4121 != GSS_C_NO_CONTEXT || + !(sc->flags & SANON_FLAG_INITIATOR)) { + major = GSS_S_BAD_STATUS; + goto out; + } + + pk.length = crypto_scalarmult_curve25519_BYTES; + pk.value = input_token->value; + + /* compute shared secret */ + major = _gss_sanon_curve25519(minor, sc, &pk, input_chan_bindings, &session_key); + if (major != GSS_S_COMPLETE) + goto out; + + flags |= GSS_C_TRANS_FLAG; + + major = _gss_sanon_import_rfc4121_context(minor, sc, flags, &session_key); + if (major != GSS_S_COMPLETE) + goto out; + + /* verify holder of key MIC */ + hok_mic.length = input_token->length - pk.length; + hok_mic.value = (uint8_t *)input_token->value + pk.length; + + major = _gss_sanon_verify_mic(minor, (gss_const_ctx_id_t)sc, + &empty, &hok_mic, NULL); + if (major != GSS_S_COMPLETE) + goto out; + } + + if (ret_flags) + *ret_flags = flags; + if (time_rec) + *time_rec = GSS_C_INDEFINITE; + +out: + if (actual_mech_type) + *actual_mech_type = GSS_SANON_X25519_MECHANISM; + + if (GSS_ERROR(major)) { + _gss_sanon_delete_sec_context(&tmp, (gss_ctx_id_t *)&sc, GSS_C_NO_BUFFER); + *context_handle = GSS_C_NO_CONTEXT; + } + _gss_secure_release_buffer(&tmp, &session_key); + + return major; +} diff --git a/lib/gssapi/sanon/inquire_context.c b/lib/gssapi/sanon/inquire_context.c new file mode 100644 index 000000000..1f540da9b --- /dev/null +++ b/lib/gssapi/sanon/inquire_context.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_inquire_context(OM_uint32 *minor, + gss_const_ctx_id_t context_handle, + gss_name_t *src_name, + gss_name_t *targ_name, + OM_uint32 *lifetime_rec, + gss_OID *mech_type, + OM_uint32 *ctx_flags, + int *locally_initiated, + int *open_context) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + *minor = 0; + + if (sc == NULL) + return GSS_S_NO_CONTEXT; + + if (src_name) + *src_name = _gss_sanon_anonymous_identity; + if (targ_name) + *targ_name = _gss_sanon_anonymous_identity; + if (lifetime_rec) + *lifetime_rec = GSS_C_INDEFINITE; + if (mech_type) + *mech_type = GSS_SANON_X25519_MECHANISM; + if (ctx_flags) + gss_inquire_context(minor, sc->rfc4121, + NULL, NULL, NULL, NULL, + ctx_flags, NULL, NULL); + if (locally_initiated) + *locally_initiated = !!(sc->flags & SANON_FLAG_INITIATOR); + if (open_context) + *open_context = !!(sc->rfc4121 != GSS_C_NO_CONTEXT); + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/inquire_cred.c b/lib/gssapi/sanon/inquire_cred.c new file mode 100644 index 000000000..6bfb05869 --- /dev/null +++ b/lib/gssapi/sanon/inquire_cred.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +_gss_sanon_inquire_cred(OM_uint32 *minor, + gss_const_cred_id_t cred_handle, + gss_name_t *name_ret, + OM_uint32 *lifetime, + gss_cred_usage_t *cred_usage, + gss_OID_set *mechanisms) +{ + if (cred_handle == GSS_C_NO_CREDENTIAL) + return GSS_S_NO_CRED; + + /* the credential handle is a reference to the cred name */ + if (name_ret) + *name_ret = (gss_name_t)cred_handle; + if (lifetime) + *lifetime = GSS_C_INDEFINITE; + if (cred_usage) + *cred_usage = GSS_C_BOTH; + if (mechanisms) + *mechanisms = GSS_C_NO_OID_SET; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/inquire_cred_by_mech.c b/lib/gssapi/sanon/inquire_cred_by_mech.c new file mode 100644 index 000000000..4f8bf66df --- /dev/null +++ b/lib/gssapi/sanon/inquire_cred_by_mech.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2003, 2006, 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_inquire_cred_by_mech(OM_uint32 *minor, + gss_const_cred_id_t cred_handle, + const gss_OID mech_type, + gss_name_t *name, + OM_uint32 *initiator_lifetime, + OM_uint32 *acceptor_lifetime, + gss_cred_usage_t *cred_usage) +{ + gss_cred_usage_t usage; + OM_uint32 major; + OM_uint32 lifetime; + + major = _gss_sanon_inquire_cred(minor, cred_handle, + name, &lifetime, &usage, NULL); + if (major) + return major; + + if (initiator_lifetime) { + if (usage == GSS_C_INITIATE || usage == GSS_C_BOTH) + *initiator_lifetime = lifetime; + else + *initiator_lifetime = 0; + } + + if (acceptor_lifetime) { + if (usage == GSS_C_ACCEPT || usage == GSS_C_BOTH) + *acceptor_lifetime = lifetime; + else + *acceptor_lifetime = 0; + } + + if (cred_usage) + *cred_usage = usage; + + *minor = 0; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/inquire_mechs_for_name.c b/lib/gssapi/sanon/inquire_mechs_for_name.c new file mode 100644 index 000000000..df7387cc6 --- /dev/null +++ b/lib/gssapi/sanon/inquire_mechs_for_name.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_inquire_mechs_for_name(OM_uint32 *minor_status, + gss_const_name_t input_name, + gss_OID_set *mech_types) +{ + OM_uint32 ret, tmp; + + ret = gss_create_empty_oid_set(minor_status, mech_types); + if (ret != GSS_S_COMPLETE) + return ret; + + ret = gss_add_oid_set_member(minor_status, + GSS_SANON_X25519_MECHANISM, + mech_types); + if (ret != GSS_S_COMPLETE) + gss_release_oid_set(&tmp, mech_types); + + return ret; +} diff --git a/lib/gssapi/sanon/inquire_names_for_mech.c b/lib/gssapi/sanon/inquire_names_for_mech.c new file mode 100644 index 000000000..c8b7f23ab --- /dev/null +++ b/lib/gssapi/sanon/inquire_names_for_mech.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sanon_locl.h" + +static gss_OID name_list[] = { + GSS_C_NT_HOSTBASED_SERVICE, + GSS_C_NT_USER_NAME, + GSS_C_NT_EXPORT_NAME, + GSS_C_NT_ANONYMOUS, + GSS_KRB5_NT_PRINCIPAL_NAME, + NULL +}; + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_inquire_names_for_mech(OM_uint32 *minor, + const gss_OID mechanism, + gss_OID_set *name_types) +{ + OM_uint32 ret, tmp; + int i; + + *minor = 0; + + if (gss_oid_equal(mechanism, GSS_SANON_X25519_MECHANISM) == 0 && + gss_oid_equal(mechanism, GSS_C_NULL_OID) == 0) { + *name_types = GSS_C_NO_OID_SET; + return GSS_S_BAD_MECH; + } + + ret = gss_create_empty_oid_set(minor, name_types); + if (ret != GSS_S_COMPLETE) + return ret; + + for (i = 0; name_list[i] != NULL; i++) { + ret = gss_add_oid_set_member(minor, + name_list[i], + name_types); + if (ret != GSS_S_COMPLETE) + break; + } + + if (ret != GSS_S_COMPLETE) + gss_release_oid_set(&tmp, name_types); + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/inquire_sec_context_by_oid.c b/lib/gssapi/sanon/inquire_sec_context_by_oid.c new file mode 100644 index 000000000..1d8bc4b10 --- /dev/null +++ b/lib/gssapi/sanon/inquire_sec_context_by_oid.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_inquire_sec_context_by_oid(OM_uint32 *minor, + gss_const_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + const sanon_ctx sc = (const sanon_ctx)context_handle; + + if (sc == NULL) + return GSS_S_NO_CONTEXT; + + *data_set = GSS_C_NO_BUFFER_SET; + + if (gss_oid_equal(desired_object, GSS_C_INQ_SSPI_SESSION_KEY) || + gss_oid_equal(desired_object, GSS_KRB5_GET_SUBKEY_X) || + gss_oid_equal(desired_object, GSS_KRB5_GET_INITIATOR_SUBKEY_X) || + gss_oid_equal(desired_object, GSS_KRB5_GET_ACCEPTOR_SUBKEY_X) || + gss_oid_equal(desired_object, GSS_KRB5_EXPORT_LUCID_CONTEXT_X)) + return gss_inquire_sec_context_by_oid(minor, sc->rfc4121, + desired_object, data_set); + else if (gss_oid_equal(desired_object, GSS_C_INQ_NEGOEX_KEY) || + gss_oid_equal(desired_object, GSS_C_INQ_NEGOEX_VERIFY_KEY)) + return _gss_sanon_inquire_negoex_key(minor, sc, desired_object, data_set); + else { + *minor = EINVAL; + return GSS_S_UNAVAILABLE; + } +} diff --git a/lib/gssapi/sanon/negoex.c b/lib/gssapi/sanon/negoex.c new file mode 100644 index 000000000..b1c5eac4f --- /dev/null +++ b/lib/gssapi/sanon/negoex.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gssspi_sanon_query_mechanism_info(OM_uint32 *minor, + gss_const_OID mech_oid, + unsigned char auth_scheme[16]) +{ + heim_assert(gss_oid_equal(mech_oid, GSS_SANON_X25519_MECHANISM), + "Invalid mechanism OID passed to query_mechanism_info"); + + *minor = 0; + + /* {DEE384FF-1086-4E86-BE78-B94170BFD376} */ + memcpy(auth_scheme, + "\xff\x84\xe3\xde\x86\x10\x86\x4e\xbe\x78\xb9\x41\x70\xbf\xd3\x76", 16); + + return GSS_S_COMPLETE; +} + +OM_uint32 +_gss_sanon_inquire_negoex_key(OM_uint32 *minor, + const sanon_ctx sc, + gss_const_OID desired_object, + gss_buffer_set_t *data_set) +{ + OM_uint32 major, tmpMinor; + int initiator_key; + uint8_t typebytes[4]; + gss_buffer_desc salt, keyvalue = GSS_C_EMPTY_BUFFER, keytype; + + if (sc->rfc4121 == GSS_C_NO_CONTEXT) { + *minor = KRB5KRB_AP_ERR_NOKEY; + return GSS_S_UNAVAILABLE; + } + + initiator_key = !!(sc->flags & SANON_FLAG_INITIATOR); + + if (gss_oid_equal(desired_object, GSS_C_INQ_NEGOEX_VERIFY_KEY)) + initiator_key ^= 1; + else if (!gss_oid_equal(desired_object, GSS_C_INQ_NEGOEX_KEY)) + return GSS_S_UNAVAILABLE; + + if (initiator_key) { + salt.length = sizeof("sanon-x25519-initiator-negoex-key") - 1; + salt.value = "sanon-x25519-initiator-negoex-key"; + } else { + salt.length = sizeof("sanon-x25519-acceptor-negoex-key") - 1; + salt.value = "sanon-x25519-acceptor-negoex-key"; + } + + _gss_mg_encode_le_uint32(KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128, typebytes); + + keytype.length = sizeof(typebytes); + keytype.value = typebytes; + + major = gss_pseudo_random(minor, sc->rfc4121, + GSS_C_PRF_KEY_FULL, &salt, + 16, &keyvalue); + if (major == GSS_S_COMPLETE) + major = gss_add_buffer_set_member(minor, &keyvalue, data_set); + if (major == GSS_S_COMPLETE) + major = gss_add_buffer_set_member(minor, &keytype, data_set); + + _gss_secure_release_buffer(&tmpMinor, &keyvalue); + + return major; +} + +static OM_uint32 +make_flags_meta_data(OM_uint32 *minor, + OM_uint32 flags, + gss_buffer_t meta_data) +{ + uint8_t data[4]; + gss_buffer_desc buffer = { sizeof(data), data }; + + _gss_mg_encode_le_uint32(flags, data); + + return _gss_copy_buffer(minor, &buffer, meta_data); +} + +OM_uint32 GSSAPI_CALLCONV +_gssspi_sanon_query_meta_data(OM_uint32 *minor, + gss_const_OID mech_oid, + gss_cred_id_t cred_handle, + gss_ctx_id_t *context_handle, + gss_const_name_t targ_name, + OM_uint32 req_flags, + gss_buffer_t meta_data) +{ + OM_uint32 major; + int local = (targ_name != GSS_C_NO_NAME); + + *minor = 0; + + if (local) { + if (!_gss_sanon_available_p(cred_handle, targ_name, req_flags)) + return GSS_S_UNAVAILABLE; + + /* + * Obscure Windows interoperability hack: use metadata to convey + * RFC4757 extended flags from initiator to acceptor. + */ + req_flags &= (GSS_C_DCE_STYLE | GSS_C_IDENTIFY_FLAG | GSS_C_EXTENDED_ERROR_FLAG); + if (req_flags) { + major = make_flags_meta_data(minor, req_flags, meta_data); + if (major != GSS_S_COMPLETE) + return major; + } + } + + return GSS_S_COMPLETE; +} + +static OM_uint32 +parse_flags_meta_data(OM_uint32 *minor, + gss_const_buffer_t meta_data, + OM_uint32 *flags) +{ + *minor = 0; + *flags = 0; + + if (meta_data->length == 0) + return GSS_S_COMPLETE; + + if (meta_data->length < 4) + return GSS_S_DEFECTIVE_TOKEN; + + _gss_mg_decode_le_uint32(meta_data->value, flags); + + return GSS_S_COMPLETE; +} + +OM_uint32 GSSAPI_CALLCONV +_gssspi_sanon_exchange_meta_data(OM_uint32 *minor, + gss_const_OID mech_oid, + gss_cred_id_t cred_handle, + gss_ctx_id_t *context_handle, + gss_const_name_t targ_name, + OM_uint32 req_flags, + gss_const_buffer_t meta_data) +{ + sanon_ctx sc = (sanon_ctx)*context_handle; + int local = (targ_name != GSS_C_NO_NAME); + OM_uint32 major, init_flags; + + *minor = 0; + + if (local) + return GSS_S_COMPLETE; + + if (sc == NULL) { + sc = calloc(1, sizeof(*sc)); + if (sc == NULL) { + *minor = ENOMEM; + return GSS_S_FAILURE; + } + *context_handle = (gss_ctx_id_t)sc; + } + + major = parse_flags_meta_data(minor, meta_data, &init_flags); + if (major != GSS_S_COMPLETE) + return major; + + sc->flags |= rfc4757_to_sanon_flags(init_flags); + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/process_context_token.c b/lib/gssapi/sanon/process_context_token.c new file mode 100644 index 000000000..077c8cba8 --- /dev/null +++ b/lib/gssapi/sanon/process_context_token.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +_gss_sanon_process_context_token(OM_uint32 *minor, + gss_const_ctx_id_t context_handle, + const gss_buffer_t token_buffer) +{ + *minor = 0; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/release_cred.c b/lib/gssapi/sanon/release_cred.c new file mode 100644 index 000000000..aa9527294 --- /dev/null +++ b/lib/gssapi/sanon/release_cred.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_release_cred(OM_uint32 *minor, + gss_cred_id_t *cred_handle) +{ + *minor = 0; + *cred_handle = GSS_C_NO_CREDENTIAL; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/release_name.c b/lib/gssapi/sanon/release_name.c new file mode 100644 index 000000000..7ba788c34 --- /dev/null +++ b/lib/gssapi/sanon/release_name.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "sanon_locl.h" + +OM_uint32 GSSAPI_CALLCONV +_gss_sanon_release_name(OM_uint32 *minor, + gss_name_t *input_name) +{ + *minor = 0; + *input_name = GSS_C_NO_NAME; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/sanon/sanon_locl.h b/lib/gssapi/sanon/sanon_locl.h new file mode 100644 index 000000000..7fab880eb --- /dev/null +++ b/lib/gssapi/sanon/sanon_locl.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2019-2020, AuriStor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SANON_LOCL_H +#define SANON_LOCL_H 1 + +#include + +#include /* for _krb5_SP800_108_HMAC_KDF() */ + +#include + +#include +#include /* for GSS_KRB5_S_XXX */ + +#include "mech/mech_locl.h" + +/* context is initiator context */ +#define SANON_FLAG_INITIATOR 0x0001 + +/* RFC 4757 extended flags */ +#define SANON_FLAG_DCE_STYLE 0x1000 +#define SANON_FLAG_IDENTIFY 0x2000 +#define SANON_FLAG_EXTENDED_ERROR 0x4000 + +typedef struct sanon_ctx_desc { + /* X25519 ECDH secret key */ + uint8_t sk[crypto_scalarmult_curve25519_BYTES]; + /* X25519 ECDH public key */ + uint8_t pk[crypto_scalarmult_curve25519_BYTES]; + /* SANON_FLAG_xxx */ + uint32_t flags; + /* krb5 context for message protection/PRF */ + gss_ctx_id_t rfc4121; +} *sanon_ctx; + +extern gss_name_t _gss_sanon_anonymous_identity; +extern gss_name_t _gss_sanon_non_anonymous_identity; + +extern gss_cred_id_t _gss_sanon_anonymous_cred; +extern gss_cred_id_t _gss_sanon_non_anonymous_cred; + +#include "sanon-private.h" + +#define SANON_WELLKNOWN_USER_NAME "WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS" +#define SANON_WELLKNOWN_USER_NAME_LEN (sizeof(SANON_WELLKNOWN_USER_NAME) - 1) + +extern gss_buffer_t _gss_sanon_wellknown_user_name; + +#define SANON_WELLKNOWN_SERVICE_NAME "WELLKNOWN@ANONYMOUS" +#define SANON_WELLKNOWN_SERVICE_NAME_LEN (sizeof(SANON_WELLKNOWN_SERVICE_NAME) - 1) + +extern gss_buffer_t _gss_sanon_wellknown_service_name; + +static inline int +buffer_equal_p(gss_const_buffer_t b1, gss_const_buffer_t b2) +{ + return b1->length == b2->length && + memcmp(b1->value, b2->value, b2->length) == 0; +} + +static inline OM_uint32 +sanon_to_rfc4757_flags(uint32_t flags) +{ + OM_uint32 ret = 0; + + if (flags & SANON_FLAG_DCE_STYLE) + ret |= GSS_C_DCE_STYLE; + if (flags & SANON_FLAG_IDENTIFY) + ret |= GSS_C_IDENTIFY_FLAG; + if (flags & SANON_FLAG_EXTENDED_ERROR) + ret |= GSS_C_EXTENDED_ERROR_FLAG; + + return ret; +} + +static inline uint32_t +rfc4757_to_sanon_flags(OM_uint32 flags) +{ + uint32_t ret = 0; + + if (flags & GSS_C_DCE_STYLE) + ret |= SANON_FLAG_DCE_STYLE; + if (flags & GSS_C_IDENTIFY_FLAG) + ret |= SANON_FLAG_IDENTIFY; + if (flags & GSS_C_EXTENDED_ERROR_FLAG) + ret |= SANON_FLAG_EXTENDED_ERROR; + + return ret; +} + +#endif /* SANON_LOCL_H */ diff --git a/lib/gssapi/test_context.c b/lib/gssapi/test_context.c index 3edc51754..1d3ece826 100644 --- a/lib/gssapi/test_context.c +++ b/lib/gssapi/test_context.c @@ -56,6 +56,7 @@ static int iov_flag = 0; static int aead_flag = 0; static int getverifymic_flag = 0; static int deleg_flag = 0; +static int anon_flag = 0; static int policy_deleg_flag = 0; static int server_no_deleg_flag = 0; static int ei_cred_flag = 0; @@ -71,6 +72,7 @@ static char *limit_enctype_string = NULL; static int version_flag = 0; static int verbose_flag = 0; static int help_flag = 0; +static char *channel_bindings = NULL; static krb5_context context; static krb5_enctype limit_enctype = 0; @@ -86,6 +88,7 @@ static struct { { "spnego", NULL /* GSS_SPNEGO_MECHANISM */ }, { "ntlm", NULL /* GSS_NTLM_MECHANISM */ }, { "sasl-digest-md5", NULL /* GSS_SASL_DIGEST_MD5_MECHANISM */ }, + { "sanon-x25519", NULL /* GSS_SASL_SANON_X25519_MECHANISM */ }, { "test_negoex_1", NULL }, { "test_negoex_2", NULL }, }; @@ -97,8 +100,9 @@ init_o2n(void) o2n[1].oid = GSS_SPNEGO_MECHANISM; o2n[2].oid = GSS_NTLM_MECHANISM; o2n[3].oid = GSS_SASL_DIGEST_MD5_MECHANISM; - o2n[4].oid = &test_negoex_1_mech; - o2n[5].oid = &test_negoex_2_mech; + o2n[4].oid = GSS_SANON_X25519_MECHANISM; + o2n[5].oid = &test_negoex_1_mech; + o2n[6].oid = &test_negoex_2_mech; } static gss_OID @@ -168,6 +172,8 @@ loop(gss_OID mechoid, OM_uint32 flags = 0, ret_cflags, ret_sflags; gss_OID actual_mech_client; gss_OID actual_mech_server; + struct gss_channel_bindings_struct channel_bindings_data; + gss_channel_bindings_t channel_bindings_p = GSS_C_NO_CHANNEL_BINDINGS; *actual_mech = GSS_C_NO_OID; @@ -177,6 +183,8 @@ loop(gss_OID mechoid, if (mutual_auth_flag) flags |= GSS_C_MUTUAL_FLAG; + if (anon_flag) + flags |= GSS_C_ANON_FLAG; if (dce_style_flag) flags |= GSS_C_DCE_STYLE; if (deleg_flag) @@ -197,6 +205,12 @@ loop(gss_OID mechoid, input_token.length = 0; input_token.value = NULL; + if (channel_bindings) { + channel_bindings_data.application_data.length = strlen(channel_bindings); + channel_bindings_data.application_data.value = channel_bindings; + channel_bindings_p = &channel_bindings_data; + } + while (!server_done || !client_done) { num_loops++; @@ -209,7 +223,7 @@ loop(gss_OID mechoid, mechoid, flags, 0, - NULL, + channel_bindings_p, &input_token, &actual_mech_client, &output_token, @@ -237,7 +251,7 @@ loop(gss_OID mechoid, sctx, GSS_C_NO_CREDENTIAL, &output_token, - GSS_C_NO_CHANNEL_BINDINGS, + channel_bindings_p, &src_name, &actual_mech_server, &input_token, @@ -328,6 +342,34 @@ loop(gss_OID mechoid, printf("server time offset: %d\n", server_time_offset); printf("client time offset: %d\n", client_time_offset); printf("num loops %d\n", num_loops); + printf("flags: "); + if (ret_cflags & GSS_C_DELEG_FLAG) + printf("deleg "); + if (ret_cflags & GSS_C_MUTUAL_FLAG) + printf("mutual "); + if (ret_cflags & GSS_C_REPLAY_FLAG) + printf("replay "); + if (ret_cflags & GSS_C_SEQUENCE_FLAG) + printf("sequence "); + if (ret_cflags & GSS_C_CONF_FLAG) + printf("conf "); + if (ret_cflags & GSS_C_INTEG_FLAG) + printf("integ "); + if (ret_cflags & GSS_C_ANON_FLAG) + printf("anon "); + if (ret_cflags & GSS_C_PROT_READY_FLAG) + printf("prot-ready "); + if (ret_cflags & GSS_C_TRANS_FLAG) + printf("trans "); + if (ret_cflags & GSS_C_DCE_STYLE) + printf("dce-style "); + if (ret_cflags & GSS_C_IDENTIFY_FLAG) + printf("identify " ); + if (ret_cflags & GSS_C_EXTENDED_ERROR_FLAG) + printf("extended-error " ); + if (ret_cflags & GSS_C_DELEG_POLICY_FLAG) + printf("deleg-policy " ); + printf("\n"); } } @@ -625,6 +667,8 @@ static struct getargs args[] = { {"client-keytab",0, arg_string, &client_keytab, "client keytab", NULL }, {"client-name", 0, arg_string, &client_name, "client name", NULL }, {"client-password", 0, arg_string, &client_password, "client password", NULL }, + {"anonymous", 0, arg_flag, &anon_flag, "anonymous auth", NULL }, + {"channel-bindings", 0, arg_string, &channel_bindings, "channel binding data", NULL }, {"limit-enctype",0, arg_string, &limit_enctype_string, "enctype", NULL }, {"dce-style",0, arg_flag, &dce_style_flag, "dce-style", NULL }, {"wrapunwrap",0, arg_flag, &wrapunwrap_flag, "wrap/unwrap", NULL }, @@ -668,7 +712,7 @@ main(int argc, char **argv) gss_cred_id_t client_cred = GSS_C_NO_CREDENTIAL, deleg_cred = GSS_C_NO_CREDENTIAL; gss_name_t cname = GSS_C_NO_NAME; gss_buffer_desc credential_data = GSS_C_EMPTY_BUFFER; - gss_OID_desc oids[6]; + gss_OID_desc oids[7]; gss_OID_set_desc mechoid_descs; gss_OID_set mechoids = GSS_C_NO_OID_SET; gss_key_value_element_desc client_cred_elements[2]; @@ -824,7 +868,7 @@ main(int argc, char **argv) &client_cred, &actual_mechs, NULL); - if (GSS_ERROR(maj_stat)) + if (GSS_ERROR(maj_stat) && !anon_flag) errx(1, "gss_acquire_cred: %s", gssapi_err(maj_stat, min_stat, GSS_C_NO_OID)); } @@ -840,6 +884,17 @@ main(int argc, char **argv) printf("\n"); } + if (gss_oid_equal(mechoid, GSS_SPNEGO_MECHANISM) && mechs_string) { + maj_stat = gss_set_neg_mechs(&min_stat, client_cred, mechoids); + if (GSS_ERROR(maj_stat)) + errx(1, "gss_set_neg_mechs: %s", + gssapi_err(maj_stat, min_stat, GSS_SPNEGO_MECHANISM)); + + mechoid_descs.elements = GSS_SPNEGO_MECHANISM; + mechoid_descs.count = 1; + mechoids = &mechoid_descs; + } + if (ei_cred_flag) { gss_cred_id_t cred2 = GSS_C_NO_CREDENTIAL; gss_buffer_desc cb; diff --git a/lib/gssapi/test_cred.c b/lib/gssapi/test_cred.c index 7ebab9a24..9eaabda0a 100644 --- a/lib/gssapi/test_cred.c +++ b/lib/gssapi/test_cred.c @@ -46,6 +46,8 @@ #include #include +static int anon_flag = 0; + static void gss_print_errors (int min_stat) { @@ -113,6 +115,7 @@ acquire_add_release_add(gss_name_t name, gss_cred_usage_t usage) { OM_uint32 maj_stat, min_stat; gss_cred_id_t cred, cred2, cred3; + gss_OID mech_oid = anon_flag ? GSS_SANON_X25519_MECHANISM : GSS_KRB5_MECHANISM; maj_stat = gss_acquire_cred(&min_stat, name, GSS_C_INDEFINITE, @@ -127,7 +130,7 @@ acquire_add_release_add(gss_name_t name, gss_cred_usage_t usage) maj_stat = gss_add_cred(&min_stat, cred, GSS_C_NO_NAME, - GSS_KRB5_MECHANISM, + mech_oid, usage, GSS_C_INDEFINITE, GSS_C_INDEFINITE, @@ -146,7 +149,7 @@ acquire_add_release_add(gss_name_t name, gss_cred_usage_t usage) maj_stat = gss_add_cred(&min_stat, cred2, GSS_C_NO_NAME, - GSS_KRB5_MECHANISM, + mech_oid, GSS_C_BOTH, GSS_C_INDEFINITE, GSS_C_INDEFINITE, @@ -170,6 +173,7 @@ static int version_flag = 0; static int help_flag = 0; static struct getargs args[] = { + {"anonymous", 0, arg_flag, &anon_flag, "try anonymous creds", NULL }, {"version", 0, arg_flag, &version_flag, "print version", NULL }, {"help", 0, arg_flag, &help_flag, NULL, NULL } }; diff --git a/lib/gssapi/test_names.c b/lib/gssapi/test_names.c index 654661153..e19531350 100644 --- a/lib/gssapi/test_names.c +++ b/lib/gssapi/test_names.c @@ -83,9 +83,11 @@ gss_err(int exitval, int status, const char *fmt, ...) static int version_flag = 0; static int help_flag = 0; +static int anon_flag = 0; static struct getargs args[] = { {"version", 0, arg_flag, &version_flag, "print version", NULL }, + {"anonymous", 0, arg_flag, &anon_flag, "test anonymous names", NULL }, {"help", 0, arg_flag, &help_flag, NULL, NULL } }; @@ -107,6 +109,7 @@ main(int argc, char **argv) int optidx = 0; char *str; int len, equal; + gss_OID mech_oid; setprogname(argv[0]); if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) @@ -130,7 +133,8 @@ main(int argc, char **argv) */ str = NULL; - len = asprintf(&str, "ftp@freeze-arrow.mit.edu"); + len = asprintf(&str, anon_flag ? + "WELLKNOWN@ANONYMOUS" : "ftp@freeze-arrow.mit.edu"); if (len < 0 || str == NULL) errx(1, "asprintf"); @@ -144,9 +148,14 @@ main(int argc, char **argv) gss_err(1, min_stat, "import name error"); free(str); + if (anon_flag) + mech_oid = GSS_SANON_X25519_MECHANISM; + else + mech_oid = GSS_KRB5_MECHANISM; + maj_stat = gss_canonicalize_name (&min_stat, name, - GSS_KRB5_MECHANISM, + mech_oid, &MNname); if (maj_stat != GSS_S_COMPLETE) gss_err(1, min_stat, "canonicalize name error"); @@ -171,8 +180,8 @@ main(int argc, char **argv) maj_stat = gss_compare_name(&min_stat, MNname, MNname2, &equal); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_compare_name"); - if (!equal) - errx(1, "names not equal"); + if (equal == anon_flag) + errx(1, "names %s equal", anon_flag ? "incorrectly" : "not"); gss_release_name(&min_stat, &MNname2); gss_release_buffer(&min_stat, &name_buffer); @@ -234,5 +243,39 @@ main(int argc, char **argv) gss_release_buffer(&min_stat, &name_buffer); #endif + if (anon_flag) { + /* check anonymous name canonicalizes to well known name */ + gss_OID name_type; + + name_buffer.length = 0; + name_buffer.value = NULL; + + maj_stat = gss_import_name(&min_stat, &name_buffer, + GSS_C_NT_ANONYMOUS, &name); + if (maj_stat != GSS_S_COMPLETE) + gss_err(1, min_stat, "import (anon) name error"); + + maj_stat = gss_canonicalize_name(&min_stat, name, + GSS_SANON_X25519_MECHANISM, + &MNname); + if (maj_stat != GSS_S_COMPLETE) + gss_err(1, min_stat, "canonicalize (anon) name error"); + + maj_stat = gss_display_name(&min_stat, MNname, + &name_buffer, &name_type); + if (maj_stat != GSS_S_COMPLETE) + gss_err(1, min_stat, "display_name (anon) name error"); + + if (!gss_oid_equal(name_type, GSS_C_NT_ANONYMOUS)) + gss_err(1, 0, "display name type not anonymous"); + if (memcmp(name_buffer.value, "WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS", + sizeof("WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS") - 1) != 0) + gss_err(1, 0, "display name string not well known anonymous name"); + + gss_release_name(&min_stat, &MNname); + gss_release_name(&min_stat, &name); + gss_release_buffer(&min_stat, &name_buffer); + } + return 0; } diff --git a/lib/gssapi/version-script.map b/lib/gssapi/version-script.map index 6db230b9d..0a731c430 100644 --- a/lib/gssapi/version-script.map +++ b/lib/gssapi/version-script.map @@ -171,6 +171,7 @@ HEIMDAL_GSS_2.0 { __gss_krb5_mechanism_oid_desc; __gss_ntlm_mechanism_oid_desc; __gss_spnego_mechanism_oid_desc; + __gss_sanon_x25519_mechanism_oid_desc; __gss_c_ma_mech_concrete_oid_desc; __gss_c_ma_mech_pseudo_oid_desc; __gss_c_ma_mech_composite_oid_desc; diff --git a/lib/hcrypto/x25519/NTMakefile b/lib/hcrypto/x25519/NTMakefile index 3b715ca7b..408f2402b 100644 --- a/lib/hcrypto/x25519/NTMakefile +++ b/lib/hcrypto/x25519/NTMakefile @@ -35,11 +35,11 @@ RELDIR=lib\hcrypto\x25519 intcflags=-I$(SRC)\lib\hcrypto -libx25519_OBJs= \ +LIBX25519_OBJS= \ $(OBJ)\ed25519_ref10.obj \ $(OBJ)\x25519_ref10.obj -$(LIBX25519): $(libx25519_OBJs) +$(LIBX25519): $(LIBX25519_OBJS) $(LIBCON) all:: $(LIBX25519) diff --git a/lib/heimdal/NTMakefile b/lib/heimdal/NTMakefile index b206cd3a8..42d51ef27 100644 --- a/lib/heimdal/NTMakefile +++ b/lib/heimdal/NTMakefile @@ -45,6 +45,7 @@ DLLDEPS= \ $(LIBSQLITE) \ $(LIBWIND) \ $(LIBLTM) \ + $(LIBX25519) \ $(LIBHEIMBASE) DLLSDKDEPS= \ diff --git a/lib/krb5/libkrb5-exports.def.in b/lib/krb5/libkrb5-exports.def.in index db4a72e2a..a35e3961d 100644 --- a/lib/krb5/libkrb5-exports.def.in +++ b/lib/krb5/libkrb5-exports.def.in @@ -782,6 +782,7 @@ EXPORTS _krb5_build_authenticator _krb5_kt_client_default_name _krb5_have_debug + _krb5_SP800_108_HMAC_KDF ; Shared with libkadm5 _krb5_load_plugins diff --git a/lib/krb5/version-script.map b/lib/krb5/version-script.map index fcf1415cc..5d0581b70 100644 --- a/lib/krb5/version-script.map +++ b/lib/krb5/version-script.map @@ -774,6 +774,7 @@ HEIMDAL_KRB5_2.0 { _krb5_build_authenticator; _krb5_kt_client_default_name; _krb5_have_debug; + _krb5_SP800_108_HMAC_KDF; # Shared with libkadm5 _krb5_load_plugins; diff --git a/tests/gss/check-basic.in b/tests/gss/check-basic.in index ea077140d..d4916bd46 100644 --- a/tests/gss/check-basic.in +++ b/tests/gss/check-basic.in @@ -125,22 +125,25 @@ ${acquire_cred} \ echo "keytab w/ wrong name" ${acquire_cred} \ - --acquire-type=accept \ + --acquire-type=accept --kerberos \ --acquire-name=host@host2.test.h5l.se 2>/dev/null && exit 1 echo "init using keytab" ${acquire_cred} \ + --kerberos \ --acquire-type=initiate \ --acquire-name=host@host.test.h5l.se > /dev/null || exit 1 echo "init using keytab (loop 10)" ${acquire_cred} \ + --kerberos \ --acquire-type=initiate \ --loops=10 \ --acquire-name=host@host.test.h5l.se > /dev/null || exit 1 echo "init using keytab (loop 10, target)" ${acquire_cred} \ + --kerberos \ --acquire-type=initiate \ --loops=10 \ --target=host@host.test.h5l.se \ @@ -163,6 +166,7 @@ ${acquire_cred} \ echo "init using existing cc" ${acquire_cred} \ + --kerberos \ --name-type=user-name \ --acquire-type=initiate \ --acquire-name=user || exit 1 @@ -171,12 +175,14 @@ KRB5CCNAME=${nocache} echo "fail init using existing cc" ${acquire_cred} \ + --kerberos \ --name-type=user-name \ --acquire-type=initiate \ --acquire-name=user 2>/dev/null && exit 1 echo "use gss_krb5_ccache_name for user" ${acquire_cred} \ + --kerberos \ --name-type=user-name \ --ccache=${cache} \ --acquire-type=initiate \ @@ -194,11 +200,13 @@ KRB5_KTNAME="${keytab}" echo "init using keytab" ${acquire_cred} \ + --kerberos \ --acquire-type=initiate \ --acquire-name=host@host.test.h5l.se 2>/dev/null || exit 1 echo "init using keytab (ccache)" ${acquire_cred} \ + --kerberos \ --acquire-type=initiate \ --ccache=${cache} \ --acquire-name=host@host.test.h5l.se 2>/dev/null || exit 1 diff --git a/tests/gss/check-context.in b/tests/gss/check-context.in index 0b657fc17..6d5d91352 100644 --- a/tests/gss/check-context.in +++ b/tests/gss/check-context.in @@ -130,17 +130,17 @@ ${klist} && { eval "$testfailed"; } ${context} --client-name=user1@${R} --client-password=u2 --mech-type=krb5 \ host@lucid.test.h5l.se && { eval "$testfailed"; } ${klist} && { eval "$testfailed"; } -${context} --client-name=user1@${R} --client-password=u2 --mech-type='' \ - --mech-types=krb5 host@lucid.test.h5l.se && { eval "$testfailed"; } +${context} --client-name=user1@${R} --client-password=u2 --mech-types='' \ + --mech-type=krb5 host@lucid.test.h5l.se && { eval "$testfailed"; } ${klist} && { eval "$testfailed"; } -${context} --client-name=user1@${R} --client-password=u2 --mech-type=krb5 \ - --mech-types=krb5 host@lucid.test.h5l.se && { eval "$testfailed"; } +${context} --client-name=user1@${R} --client-password=u2 --mech-types=krb5 \ + --mech-type=krb5 host@lucid.test.h5l.se && { eval "$testfailed"; } ${klist} && { eval "$testfailed"; } -${context} --client-name=user1@${R} --client-password=u2 --mech-type=all \ - --mech-types=krb5 host@lucid.test.h5l.se && { eval "$testfailed"; } +${context} --client-name=user1@${R} --client-password=u2 --mech-types=all \ + --mech-type=krb5 host@lucid.test.h5l.se && { eval "$testfailed"; } ${klist} && { eval "$testfailed"; } ${context} --client-name=user1@${R} --client-password=u2 \ - --mech-type=krb5,ntlm --mech-types=krb5 host@lucid.test.h5l.se \ + --mech-types=krb5,ntlm --mech-type=krb5 host@lucid.test.h5l.se \ && { eval "$testfailed"; } # gss_acquire_cred_with_password() must not have side-effects ${klist} && { eval "$testfailed"; } @@ -161,7 +161,8 @@ ${context} --mech-type=krb5 host@lucid.test.h5l.se > test_context.log 2>&1 && \ grep ${keytabfile} test_context.log > /dev/null || \ { echo "string missing failed"; cat test_context.log ; eval "$testfailed"; } echo "checking non existant keytabfile (spengo)" ; > messages.log -${context} --mech-type=spnego host@lucid.test.h5l.se > test_context.log 2>&1 && \ +${context} --mech-type=spnego --mech-types=spnego,krb5 \ + host@lucid.test.h5l.se > test_context.log 2>&1 && \ { eval "$testfailed"; } grep ${keytabfile} test_context.log > /dev/null || \ { echo "string missing failed"; cat test_context.log ; eval "$testfailed"; } diff --git a/tests/gss/check-negoex.in b/tests/gss/check-negoex.in index a5f9cdc31..c4b9b3907 100644 --- a/tests/gss/check-negoex.in +++ b/tests/gss/check-negoex.in @@ -178,6 +178,88 @@ echo "test_negoex_1 alert from initiator to acceptor" host@host.test.h5l.se || \ { exitcode=1 ; echo test failed; } +unset GSS_MECH_CONFIG + +echo "======test context building for sanon-x25519" +for mech in sanon-x25519 sanon-x25519iov spnego spnegoiov; do + iov="" + if [ "$mech" = "sanon-x25519iov" ] ; then + mech="sanon-x25519" + iov="--iov" + fi + if [ "$mech" = "spnegoiov" ] ; then + mech="spnego" + iov="--iov" + fi + + echo "${mech} anon-flag ${iov}" ; > messages.log + ${context} --mech-type=${mech} \ + --anonymous \ + --ret-mech-type=sanon-x25519 \ + --channel-bindings=negoex_sanon_test_h5l_se \ + --wrapunwrap ${iov} \ + host@lucid.test.h5l.se || \ + { eval "$testfailed"; } + + echo "${mech} anon-initiator ${iov}" ; > messages.log + ${context} --mech-type=${mech} \ + --client-name=WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS \ + --ret-mech-type=sanon-x25519 \ + --channel-bindings=negoex_sanon_test_h5l_se \ + --wrapunwrap ${iov} \ + host@lucid.test.h5l.se || \ + { eval "$testfailed"; } + + echo "${mech} anon-acceptor ${iov}" ; > messages.log + ${context} --mech-type=${mech} \ + --ret-mech-type=sanon-x25519 \ + --channel-bindings=negoex_sanon_test_h5l_se \ + --wrapunwrap ${iov} \ + WELLKNOWN@ANONYMOUS || \ + { eval "$testfailed"; } +done + +echo "======export-import-context for sanon-x25519" +for mech in sanon-x25519 sanon-x25519iov spnego spnegoiov; do + iov="" + if [ "$mech" = "sanon-x25519iov" ] ; then + mech="sanon-x25519" + iov="--iov" + fi + if [ "$mech" = "spnegoiov" ] ; then + mech="spnego" + iov="--iov" + fi + + echo "${mech}: export-import-context ${iov}" ; > messages.log + ${context} \ + --mech-type=${mech} \ + --anonymous \ + --export-import-context \ + --wrapunwrap ${iov} \ + --name-type=hostbased-service host@lucid.test.h5l.se || \ + { eval "$testfailed"; } + +done + +echo "======dce-style for sanon-x25519" +for mech in spnego spnegoiov; do + iov="" + if [ "$mech" = "spnegoiov" ] ; then + mech="spnego" + iov="--iov" + fi + + echo "${mech}: dce-style ${iov}" ; > messages.log + ${context} \ + --mech-type=${mech} \ + --anonymous --dce-style \ + --wrapunwrap ${iov} \ + --name-type=hostbased-service host@lucid.test.h5l.se || \ + { eval "$testfailed"; } + +done + trap "" EXIT exit $exitcode diff --git a/windows/NTMakefile.w32 b/windows/NTMakefile.w32 index 1cb646339..e41110ff8 100644 --- a/windows/NTMakefile.w32 +++ b/windows/NTMakefile.w32 @@ -596,6 +596,7 @@ LIBSL =$(LIBDIR)\libsl.lib LIBSQLITE =$(LIBDIR)\libsqlite.lib LIBVERS =$(LIBDIR)\libvers.lib LIBWIND =$(LIBDIR)\libwind.lib +LIBX25519 =$(LIBDIR)\libx25519.lib !ifdef VER_DEBUG ASM_DBG=.Debug