1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
GSSAPI Java CSharp C. Morris
INTERNET-DRAFT Novell, Inc.
draft-morris-java-gssapi-update-for-csharp-00.txt comorris@novell.com
Expires 10 March 2004 July 2004
Generic Security Service API Version 2 : Java & C# Bindings
Status of this Memo
Comments should be submitted to comorris@novell.com.
By submitting this Internet-Draft, I certify that any applicable
patent or other IPR claims of which I am aware have been disclosed, or
will be disclosed, and any of which I become aware will be disclosed,
in accordance with RFC 3668.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF), its areas, and its working groups. Note that other
groups may also distribute working documents as Internet-Drafts.
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 a "work in progress."
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/1id-abstracts.html
The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html
Abstract
The Generic Security Services Application Program Interface (GSS-API)
offers application programmers uniform access to security services
atop a variety of underlying cryptographic mechanisms. This document
proposes an update to RFC 2853, Generic Security Service API Version
2 : Java Bindings, to include C# bindings.
4.17. C# Modifications
This section describes the language dependent modifications necessary
to implement the interface in C#.
4.17.1 C# Assembly Name
The C# namespace is org.ietf.gss. See section 4.17.5 for an example.
4.17.2 C# Class Definitions
All class definitions & methods remain the same as specified in the
Java bindings.
4.17.3 C# Data Types
All data types remain the same.
4.17.4 C# Exception Handling
All exception codes remain the same as specified in the Java bindings.
However, C# does not have a 'throws' statement. Therefore, method prototypes do
not include the exception type. For example,
Java method prototype :
public abstract GSSName createName(String nameStr, Oid nameType)
throws GSSException;
Equivalent C# method prototype :
public abstract GSSName createName(String nameStr, Oid nameType);
C# does implement the throw and catch keywords, for example:
public class GSSName createName(String nameStr, Oid nameType)
{
int majorCode = 0;
...
majorCode = validateParms(nameStr, nameType);
if (majorCode)
throw new GSSException(majorCode);
...
}
4.17.5 C# Example Code
Client example :
using ietf.org.gss;
class GssapiClient
{
private static TcpClient client;
private static NetworkStream stream;
static void Main(string[] args)
{
Connect("127.0.0.1", "message from client");
try
{
GSSManager manager = GSSManager.getInstance();
Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
Oid krb5PrincipalNameType = new Oid("1.2.840.113554.1.2.2.1");
// Optionally Identify who the client wishes to be
// GSSName name = manager.createName("test@gsserver", GSSName.NT_USER_NAME);
// Obtain default credential
GSSCredential userCreds = manager.createCredential(GSSCredential.INITIATE_ONLY);
GSSName name = userCreds.getName(krb5PrincipalNameType);
Console.WriteLine("Just acquired credentials for " + name.toString());
int acceptLife = userCreds.getRemainingAcceptLifetime(new Oid("2.3.4"));
int initLife = userCreds.getRemainingInitLifetime(new Oid("1..3."));
int remLife = userCreds.getRemainingLifetime();
int usage = userCreds.getUsage();
GSSName namea = userCreds.getName();
Oid[] oa = userCreds.getMechs();
// Instantiate and initialize a security context that will be
// established with the server
GSSContext context = manager.createContext(name,
krb5Mechanism,
userCreds,
GSSContext.DEFAULT_LIFETIME);
userCreds.dispose();
// Optionally Set Context Options, must be done before iniSecContext call
context.requestMutualAuth(true);
context.requestConf(true);
context.requestInteg(true);
context.requestSequenceDet(true);
context.requestCredDeleg(true);
MemoryStream ins = new MemoryStream();
MemoryStream outs = new MemoryStream();
// loop until context is setup and no more tokens to receive
while (!context.isEstablished())
{
outs = new MemoryStream();
context.initSecContext(ins, outs);
// send token if present
if (outs.Length > 0)
{
Console.WriteLine("Sending token...");
sendToken(outs);
}
// check if we should expect more tokens
if (context.isEstablished())
break;
// another token expected from peer
Console.WriteLine("Still expecting another token from server...");
ins = recvToken();
}
//
// display context information
//
// Did the server authenticate back to client?
Console.WriteLine("\n{0} Mutual Authentication",
context.getMutualAuthState() ? "Using" : "Not using");
Console.WriteLine("Credentials were delegated = "
+ context.getCredDelegState());
Console.WriteLine("Remaining lifetime in seconds = "
+ context.getLifetime());
Console.WriteLine("Context mechanism = " + context.getMech());
Console.WriteLine("Initiator = " + context.getSrcName().toString());
Console.WriteLine("Acceptor = " + context.getTargName().toString());
Console.WriteLine("Confidentiality (i.e., privacy) is {0}available",
context.getConfState() ? "" : "not ");
Console.WriteLine("Integrity is {0}available",
context.getIntegState() ? "" : "not ");
Console.WriteLine("Is initiator = " + context.isInitiator());
Console.WriteLine("Is transferable = " + context.isTransferable());
Console.WriteLine("Is protReady = " + context.isProtReady());
Console.WriteLine("ReplayDetState = " +
context.getReplayDetState());
Console.WriteLine("SequenceDetState = " +
context.getSequenceDetState());
// perform wrap on an application supplied message
// using QOP = 0, and requesting privacy service
MessageProp msgProp = new MessageProp(0, true);
byte [] message = System.Text.Encoding.ASCII.GetBytes("Hello GSS-API!");
byte [] token = System.Text.Encoding.ASCII.GetBytes("tok");
// Byte aray method is equivalent to stream method
//byte []token = context.wrap(message, 0, appMsg.length, msgProp);
//sendToken(token);
ins = new MemoryStream();
outs = new MemoryStream();
ins.Write(token, 0, token.Length);
context.getMIC(ins, outs, msgProp);
sendToken(outs);
outs = new MemoryStream();
outs.Write(message, 0, message.Length);
sendToken(outs);
ins = new MemoryStream();
outs = new MemoryStream();
ins.Write(message, 0, message.Length);
context.wrap(ins, outs, msgProp);
sendToken(outs);
// Optionally export context to another thead
GSSContext ctx = manager.createContext(context.export());
Console.WriteLine("New context isTransferable = " + ctx.isTransferable());
Console.WriteLine("New context isInitiator = " +ctx.isInitiator());
Console.WriteLine("New context protReady = " +ctx.isProtReady());
Console.WriteLine("New context srcName = " +ctx.getSrcName().toString());
Console.WriteLine("New context targName = " +ctx.getTargName().toString());
// release the local-end of the context
ctx.dispose();
stream.Close();
Console.WriteLine("Leaving...");
}
catch (GSSException e)
{
Console.WriteLine(e.getMessage());
Console.WriteLine(e.StackTrace);
}
}
Expires 10 March 2004
|