gss: SAnon - the Simple Anonymous GSS-API mechanism
authorLuke Howard <lukeh@padl.com>
Mon, 30 Dec 2019 10:07:04 +0000 (21:07 +1100)
committerNicolas Williams <nico@twosigma.com>
Sun, 26 Apr 2020 04:19:30 +0000 (23:19 -0500)
Add support for SAnon, a simple key agreement protocol that provides no
authentication of initiator or acceptor using x25519 ECDH key exchange.
See doc/standardization/draft-howard-gss-sanon-xx.txt for a protocol
description.

53 files changed:
.gitignore
doc/standardisation/draft-howard-gss-sanon-12.txt [new file with mode: 0644]
lib/gssapi/Makefile.am
lib/gssapi/NTMakefile
lib/gssapi/gssapi/gssapi_oid.h
lib/gssapi/gssapi_mech.h
lib/gssapi/libgssapi-exports.def
lib/gssapi/mech/gss_mech_switch.c
lib/gssapi/mech/gss_oid.c
lib/gssapi/oid.txt
lib/gssapi/sanon/accept_sec_context.c [new file with mode: 0644]
lib/gssapi/sanon/acquire_cred.c [new file with mode: 0644]
lib/gssapi/sanon/add_cred.c [new file with mode: 0644]
lib/gssapi/sanon/canonicalize_name.c [new file with mode: 0644]
lib/gssapi/sanon/compare_name.c [new file with mode: 0644]
lib/gssapi/sanon/context_time.c [new file with mode: 0644]
lib/gssapi/sanon/crypto.c [new file with mode: 0644]
lib/gssapi/sanon/delete_sec_context.c [new file with mode: 0644]
lib/gssapi/sanon/display_name.c [new file with mode: 0644]
lib/gssapi/sanon/display_status.c [new file with mode: 0644]
lib/gssapi/sanon/duplicate_cred.c [new file with mode: 0644]
lib/gssapi/sanon/duplicate_name.c [new file with mode: 0644]
lib/gssapi/sanon/export_cred.c [new file with mode: 0644]
lib/gssapi/sanon/export_name.c [new file with mode: 0644]
lib/gssapi/sanon/export_sec_context.c [new file with mode: 0644]
lib/gssapi/sanon/external.c [new file with mode: 0644]
lib/gssapi/sanon/import_cred.c [new file with mode: 0644]
lib/gssapi/sanon/import_name.c [new file with mode: 0644]
lib/gssapi/sanon/import_sec_context.c [new file with mode: 0644]
lib/gssapi/sanon/init_sec_context.c [new file with mode: 0644]
lib/gssapi/sanon/inquire_context.c [new file with mode: 0644]
lib/gssapi/sanon/inquire_cred.c [new file with mode: 0644]
lib/gssapi/sanon/inquire_cred_by_mech.c [new file with mode: 0644]
lib/gssapi/sanon/inquire_mechs_for_name.c [new file with mode: 0644]
lib/gssapi/sanon/inquire_names_for_mech.c [new file with mode: 0644]
lib/gssapi/sanon/inquire_sec_context_by_oid.c [new file with mode: 0644]
lib/gssapi/sanon/negoex.c [new file with mode: 0644]
lib/gssapi/sanon/process_context_token.c [new file with mode: 0644]
lib/gssapi/sanon/release_cred.c [new file with mode: 0644]
lib/gssapi/sanon/release_name.c [new file with mode: 0644]
lib/gssapi/sanon/sanon_locl.h [new file with mode: 0644]
lib/gssapi/test_context.c
lib/gssapi/test_cred.c
lib/gssapi/test_names.c
lib/gssapi/version-script.map
lib/hcrypto/x25519/NTMakefile
lib/heimdal/NTMakefile
lib/krb5/libkrb5-exports.def.in
lib/krb5/version-script.map
tests/gss/check-basic.in
tests/gss/check-context.in
tests/gss/check-negoex.in
windows/NTMakefile.w32

index ff4787a95464178f47e209cea222438e3d1a90f0..b1d0c9e1e8ed8cc6eb3f020327c7bb58979aedca 100644 (file)
@@ -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 (file)
index 0000000..7cafc9c
--- /dev/null
@@ -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]
+\f
+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]
+\f
+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]
+\f
+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]
+\f
+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]
+\f
+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]
+\f
+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,
+              <https://www.rfc-editor.org/info/rfc2119>.
+
+   [RFC2743]  Linn, J., "Generic Security Service Application Program
+              Interface Version 2, Update 1", RFC 2743,
+              DOI 10.17487/RFC2743, January 2000,
+              <https://www.rfc-editor.org/info/rfc2743>.
+
+
+
+
+Howard                  Expires October 25, 2020                [Page 7]
+\f
+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, <https://www.rfc-editor.org/info/rfc3961>.
+
+   [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,
+              <https://www.rfc-editor.org/info/rfc4121>.
+
+   [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,
+              <https://www.rfc-editor.org/info/rfc4401>.
+
+   [RFC7748]  Langley, A., Hamburg, M., and S. Turner, "Elliptic Curves
+              for Security", RFC 7748, DOI 10.17487/RFC7748, January
+              2016, <https://www.rfc-editor.org/info/rfc7748>.
+
+   [RFC8009]  Jenkins, M., Peck, M., and K. Burgin, "AES Encryption with
+              HMAC-SHA2 for Kerberos 5", RFC 8009, DOI 10.17487/RFC8009,
+              October 2016, <https://www.rfc-editor.org/info/rfc8009>.
+
+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,
+              <https://www.rfc-editor.org/info/rfc4178>.
+
+   [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,
+              <https://www.rfc-editor.org/info/rfc4757>.
+
+   [RFC5587]  Williams, N., "Extended Generic Security Service Mechanism
+              Inquiry APIs", RFC 5587, DOI 10.17487/RFC5587, July 2009,
+              <https://www.rfc-editor.org/info/rfc5587>.
+
+
+
+
+
+
+Howard                  Expires October 25, 2020                [Page 8]
+\f
+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,
+              <https://www.rfc-editor.org/info/rfc8062>.
+
+   [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]
+\f
+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]
index 0b1c7ff3272f7b3f71d85b4ecdf6a2d4baacb05a..7263c5230080fe63f291fb09188e6b6afadb0073 100644 (file)
@@ -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 
index 185f63c4072ed60e4bb22b603518655b0f96aaca..2c5975c045073b76c91793f9cce6015731095c60 100644 (file)
@@ -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
index 55054858d0d202b171328b514973c4c1afc1607c..fabd090fd8355d535546f94abe977cb4344a855b 100644 (file)
@@ -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
  */
index 07682ca7f7dc12b754d1b3230360e4079a133160..634e16b32f8a9b581fce538cf9c8b226e91bc46b 100644 (file)
@@ -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);
 
index f1edb983f1761d72f0c192abae904f7a8600fd29..10e487f1366aa1b02acf1cd37ce863aa71e8168c 100644 (file)
@@ -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
index 9085e962ff4497b85cd1c47074a4a7e37c14bdae..9e4c96decf98726b1d69c16684f61546bdedde16 100644 (file)
@@ -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);
 }
 
index 69ff9868ccfb9df19587e561d5dda062a1f08ea2..10ec22dbeffa365114d7f33b7068973cb001930f 100644 (file)
@@ -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,
index 93bcf443ad2c69eafa31f3c90ed74d82acf61229..12e167f39ff4a73996b720465957f4500388d5f9 100644 (file)
@@ -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 (file)
index 0000000..cd0b7fd
--- /dev/null
@@ -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 (file)
index 0000000..7aedd3e
--- /dev/null
@@ -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 (file)
index 0000000..f1dfeba
--- /dev/null
@@ -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 (file)
index 0000000..fa1ade0
--- /dev/null
@@ -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 (file)
index 0000000..85b13b2
--- /dev/null
@@ -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 (file)
index 0000000..338f3ac
--- /dev/null
@@ -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 (file)
index 0000000..2a4d8e8
--- /dev/null
@@ -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 (file)
index 0000000..fdb8a85
--- /dev/null
@@ -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 (file)
index 0000000..1bd55f3
--- /dev/null
@@ -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 (file)
index 0000000..4e039c6
--- /dev/null
@@ -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 (file)
index 0000000..8c5c5d8
--- /dev/null
@@ -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 (file)
index 0000000..698e83d
--- /dev/null
@@ -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 (file)
index 0000000..06c2458
--- /dev/null
@@ -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 (file)
index 0000000..474c58c
--- /dev/null
@@ -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 (file)
index 0000000..f788dae
--- /dev/null
@@ -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 (file)
index 0000000..fa100fe
--- /dev/null
@@ -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 (file)
index 0000000..4266ef1
--- /dev/null
@@ -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 (file)
index 0000000..189308d
--- /dev/null
@@ -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 (file)
index 0000000..9aa682a
--- /dev/null
@@ -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 (file)
index 0000000..08f630e
--- /dev/null
@@ -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 (file)
index 0000000..1f540da
--- /dev/null
@@ -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 (file)
index 0000000..6bfb058
--- /dev/null
@@ -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 (file)
index 0000000..4f8bf66
--- /dev/null
@@ -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 (file)
index 0000000..df7387c
--- /dev/null
@@ -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 (file)
index 0000000..c8b7f23
--- /dev/null
@@ -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 (file)
index 0000000..1d8bc4b
--- /dev/null
@@ -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 (file)
index 0000000..b1c5eac
--- /dev/null
@@ -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 (file)
index 0000000..077c8cb
--- /dev/null
@@ -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 (file)
index 0000000..aa95272
--- /dev/null
@@ -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 (file)
index 0000000..7ba788c
--- /dev/null
@@ -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 (file)
index 0000000..7fab880
--- /dev/null
@@ -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 <config.h>
+
+#include <krb5_locl.h> /* for _krb5_SP800_108_HMAC_KDF() */
+
+#include <hcrypto/x25519_ref10.h>
+
+#include <gssapi.h>
+#include <gkrb5_err.h> /* 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 */
index 3edc5175496a4468c058bdcb8aaf8a40288a171e..1d3ece8266787bc4f534b03adbf310c0a900b402 100644 (file)
@@ -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;
index 7ebab9a249788d9edaf61786c52072972e8e1131..9eaabda0a21c4a0d024c26b4ed4a2f08124ca0a2 100644 (file)
@@ -46,6 +46,8 @@
 #include <err.h>
 #include <getarg.h>
 
+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 }
 };
index 6546611539557b1968b5040495992027243dc491..e195313505c4e5611b9aaf235e7b76a49e655716 100644 (file)
@@ -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;
 }
index 6db230b9dc6953b779fce7f0070bc890c7663216..0a731c4303474aef37d5eaac893d729c384e9498 100644 (file)
@@ -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;
index 3b715ca7b50e758794a59b673554e60b0c54ae17..408f2402bf2ce827b224726cfad362ef13421d6b 100644 (file)
@@ -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)
index b206cd3a8ba19eea193a1857aa3313c56b5966e1..42d51ef272f538e8081c7bd4c8ff6739e5cc47b6 100644 (file)
@@ -45,6 +45,7 @@ DLLDEPS= \
        $(LIBSQLITE)    \
        $(LIBWIND)      \
        $(LIBLTM)       \
+       $(LIBX25519)    \
        $(LIBHEIMBASE)
 
 DLLSDKDEPS= \
index db4a72e2a0b2d0aa86ee427cd9a46142f107afcd..a35e3961d331db7408d911447ea761b7037aaf33 100644 (file)
@@ -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
index fcf1415cc50287e864bead974c7ab8721332bfe8..5d0581b703af154e9e6ae6c4eceeae1e2cc4b45c 100644 (file)
@@ -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;
index ea077140d00b47d14804511f73dac0342cd390bc..d4916bd46d4bb61f7905351bf945cd40dbb907df 100644 (file)
@@ -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
index 0b657fc178c53289adbadade9796bfe4715b7279..6d5d913526fc4bc03804a6af04513da4664c6e8c 100644 (file)
@@ -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"; }
index a5f9cdc310c90e8f1a28c34d9f14154934789d48..c4b9b3907f6375cf43151782fd592b0d6e30cd9a 100644 (file)
@@ -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
index 1cb646339cf0009d770644a81bc3467e89e87b16..e41110ff8e0ddca3da590af5bda427d1ffa0d9dc 100644 (file)
@@ -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