提交 84a9b032 编写于 作者: W weijun

6975866: api/org_ietf/jgss/GSSContext/index.html#wrapUnwrapIOTest started to fail since jdk7 b102

Reviewed-by: valeriep
上级 c86e1caa
/*
* Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -710,29 +710,21 @@ class CipherHelper {
* where HMAC is on {16-byte confounder | plaintext | 16-byte token_header}
* HMAC is not encrypted; it is appended at the end.
*/
void encryptData(WrapToken_v2 token, byte[] confounder, byte[] tokenHeader,
byte[] plaintext, int start, int len, int key_usage, OutputStream os)
throws GSSException, IOException {
byte[] encryptData(WrapToken_v2 token, byte[] confounder, byte[] tokenHeader,
byte[] plaintext, int start, int len, int key_usage)
throws GSSException {
byte[] ctext = null;
switch (etype) {
case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96:
ctext = aes128Encrypt(confounder, tokenHeader,
plaintext, start, len, key_usage);
break;
case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
ctext = aes256Encrypt(confounder, tokenHeader,
plaintext, start, len, key_usage);
break;
default:
throw new GSSException(GSSException.FAILURE, -1,
"Unsupported etype: " + etype);
case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96:
return aes128Encrypt(confounder, tokenHeader,
plaintext, start, len, key_usage);
case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
return aes256Encrypt(confounder, tokenHeader,
plaintext, start, len, key_usage);
default:
throw new GSSException(GSSException.FAILURE, -1,
"Unsupported etype: " + etype);
}
// Krb5Token.debug("EncryptedData = " +
// Krb5Token.getHexBytes(ctext) + "\n");
// Write to stream
os.write(ctext);
}
void encryptData(WrapToken token, byte[] confounder, byte[] plaintext,
......
/*
* Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -29,12 +29,11 @@ import org.ietf.jgss.*;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
/**
* This class represents the new format of GSS MIC tokens, as specified
* in draft-ietf-krb-wg-gssapi-cfx-07.txt
* in RFC 4121
*
* MIC tokens = { 16-byte token-header | HMAC }
* where HMAC is on { plaintext | 16-byte token-header }
......@@ -48,12 +47,11 @@ class MicToken_v2 extends MessageToken_v2 {
byte[] tokenBytes, int tokenOffset, int tokenLen,
MessageProp prop) throws GSSException {
super(Krb5Token.MIC_ID_v2, context,
tokenBytes, tokenOffset, tokenLen, prop);
tokenBytes, tokenOffset, tokenLen, prop);
}
public MicToken_v2(Krb5Context context,
InputStream is, MessageProp prop)
throws GSSException {
public MicToken_v2(Krb5Context context, InputStream is, MessageProp prop)
throws GSSException {
super(Krb5Token.MIC_ID_v2, context, is, prop);
}
......@@ -64,7 +62,6 @@ class MicToken_v2 extends MessageToken_v2 {
}
public void verify(InputStream data) throws GSSException {
byte[] dataBytes = null;
try {
dataBytes = new byte[data.available()];
......@@ -79,7 +76,7 @@ class MicToken_v2 extends MessageToken_v2 {
public MicToken_v2(Krb5Context context, MessageProp prop,
byte[] data, int pos, int len)
throws GSSException {
throws GSSException {
super(Krb5Token.MIC_ID_v2, context);
// debug("Application data to MicToken verify is [" +
......@@ -89,7 +86,7 @@ class MicToken_v2 extends MessageToken_v2 {
}
public MicToken_v2(Krb5Context context, MessageProp prop, InputStream data)
throws GSSException, IOException {
throws GSSException, IOException {
super(Krb5Token.MIC_ID_v2, context);
byte[] dataBytes = new byte[data.available()];
......@@ -101,22 +98,21 @@ class MicToken_v2 extends MessageToken_v2 {
genSignAndSeqNumber(prop, dataBytes, 0, dataBytes.length);
}
public int encode(byte[] outToken, int offset)
throws IOException, GSSException {
public byte[] encode() throws IOException {
// XXX Fine tune this initial size
ByteArrayOutputStream bos = new ByteArrayOutputStream(50);
encode(bos);
return bos.toByteArray();
}
// Token is small
ByteArrayOutputStream bos = new ByteArrayOutputStream();
super.encode(bos);
byte[] token = bos.toByteArray();
public int encode(byte[] outToken, int offset) throws IOException {
byte[] token = encode();
System.arraycopy(token, 0, outToken, offset, token.length);
return token.length;
}
public byte[] encode() throws IOException, GSSException {
// XXX Fine tune this initial size
ByteArrayOutputStream bos = new ByteArrayOutputStream(50);
encode(bos);
return bos.toByteArray();
public void encode(OutputStream os) throws IOException {
encodeHeader(os);
os.write(checksum);
}
}
/*
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -27,14 +27,11 @@ package sun.security.jgss.krb5;
import org.ietf.jgss.*;
import sun.security.jgss.*;
import java.security.GeneralSecurityException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import sun.security.krb5.Confounder;
import sun.security.krb5.KrbException;
/**
* This class represents a token emitted by the GSSContext.wrap()
......@@ -336,24 +333,29 @@ class WrapToken extends MessageToken {
// debug("\t\tNo encryption was performed by peer.\n");
readFully(is, confounder);
// Data is always a multiple of 8 with this GSS Mech
// Copy all but last block as they are
int numBlocks = (dataSize - CONFOUNDER_SIZE)/8 - 1;
int offset = dataBufOffset;
for (int i = 0; i < numBlocks; i++) {
readFully(is, dataBuf, offset, 8);
offset += 8;
if (cipherHelper.isArcFour()) {
padding = pads[1];
readFully(is, dataBuf, dataBufOffset, dataSize-CONFOUNDER_SIZE-1);
} else {
// Data is always a multiple of 8 with this GSS Mech
// Copy all but last block as they are
int numBlocks = (dataSize - CONFOUNDER_SIZE)/8 - 1;
int offset = dataBufOffset;
for (int i = 0; i < numBlocks; i++) {
readFully(is, dataBuf, offset, 8);
offset += 8;
}
byte[] finalBlock = new byte[8];
readFully(is, finalBlock);
int padSize = finalBlock[7];
padding = pads[padSize];
// debug("\t\tPadding applied was: " + padSize + "\n");
System.arraycopy(finalBlock, 0, dataBuf, offset,
finalBlock.length - padSize);
}
byte[] finalBlock = new byte[8];
readFully(is, finalBlock);
int padSize = finalBlock[7];
padding = pads[padSize];
// debug("\t\tPadding applied was: " + padSize + "\n");
System.arraycopy(finalBlock, 0, dataBuf, offset,
finalBlock.length - padSize);
}
} catch (IOException e) {
throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1,
......
/*
* Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -27,66 +27,30 @@ package sun.security.jgss.krb5;
import org.ietf.jgss.*;
import sun.security.jgss.*;
import java.security.GeneralSecurityException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import sun.security.krb5.Confounder;
import sun.security.krb5.KrbException;
/**
* This class represents the new format of GSS tokens, as specified in
* draft-ietf-krb-wg-gssapi-cfx-07.txt, emitted by the GSSContext.wrap()
* call. It is a MessageToken except that it also contains plaintext or
* encrypted data at the end. A WrapToken has certain other rules that are
* peculiar to it and different from a MICToken, which is another type of
* MessageToken. All data in a WrapToken is prepended by a random counfounder
* of 16 bytes. Thus, all application data is replaced by
* (confounder || data || tokenHeader || checksum).
* This class represents the new format of GSS tokens, as specified in RFC
* 4121, emitted by the GSSContext.wrap() call. It is a MessageToken except
* that it also contains plaintext or encrypted data at the end. A WrapToken
* has certain other rules that are peculiar to it and different from a
* MICToken, which is another type of MessageToken. All data in a WrapToken is
* prepended by a random confounder of 16 bytes. Thus, all application data
* is replaced by (confounder || data || tokenHeader || checksum).
*
* @author Seema Malkani
*/
class WrapToken_v2 extends MessageToken_v2 {
/**
* The size of the random confounder used in a WrapToken.
*/
static final int CONFOUNDER_SIZE = 16;
/*
* A token may come in either in an InputStream or as a
* byte[]. Store a reference to it in either case and process
* it's data only later when getData() is called and
* decryption/copying is needed to be done. Note that JCE can
* decrypt both from a byte[] and from an InputStream.
*/
private boolean readTokenFromInputStream = true;
private InputStream is = null;
private byte[] tokenBytes = null;
private int tokenOffset = 0;
private int tokenLen = 0;
/*
* Application data may come from an InputStream or from a
* byte[]. However, it will always be stored and processed as a
* byte[] since
* (a) the MessageDigest class only accepts a byte[] as input and
* (b) It allows writing to an OuputStream via a CipherOutputStream.
*/
private byte[] dataBytes = null;
private int dataOffset = 0;
private int dataLen = 0;
// the len of the token data:
// (confounder || data || tokenHeader || checksum)
private int dataSize = 0;
// Accessed by CipherHelper
byte[] confounder = null;
private boolean privacy = false;
private boolean initiator = true;
private final boolean privacy;
/**
* Constructs a WrapToken from token bytes obtained from the
......@@ -104,30 +68,9 @@ class WrapToken_v2 extends MessageToken_v2 {
byte[] tokenBytes, int tokenOffset, int tokenLen,
MessageProp prop) throws GSSException {
// Just parse the MessageToken part first
super(Krb5Token.WRAP_ID_v2, context,
tokenBytes, tokenOffset, tokenLen, prop);
this.readTokenFromInputStream = false;
// rotate token bytes as per RRC
byte[] new_tokenBytes = new byte[tokenLen];
if (rotate_left(tokenBytes, tokenOffset, new_tokenBytes, tokenLen)) {
this.tokenBytes = new_tokenBytes;
this.tokenOffset = 0;
} else {
this.tokenBytes = tokenBytes;
this.tokenOffset = tokenOffset;
}
// Will need the token bytes again when extracting data
this.tokenLen = tokenLen;
this.privacy = prop.getPrivacy();
dataSize = tokenLen - TOKEN_HEADER_SIZE;
// save initiator
this.initiator = context.isInitiator();
}
/**
......@@ -145,27 +88,8 @@ class WrapToken_v2 extends MessageToken_v2 {
InputStream is, MessageProp prop)
throws GSSException {
// Just parse the MessageToken part first
super(Krb5Token.WRAP_ID_v2, context, is, prop);
// Will need the token bytes again when extracting data
this.is = is;
this.privacy = prop.getPrivacy();
// get the token length
try {
this.tokenLen = is.available();
} catch (IOException e) {
throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1,
getTokenName(getTokenId())
+ ": " + e.getMessage());
}
// data size
dataSize = tokenLen - TOKEN_HEADER_SIZE;
// save initiator
this.initiator = context.isInitiator();
}
/**
......@@ -177,13 +101,9 @@ class WrapToken_v2 extends MessageToken_v2 {
*/
public byte[] getData() throws GSSException {
byte[] temp = new byte[dataSize];
byte[] temp = new byte[tokenDataLen];
int len = getData(temp, 0);
// len obtained is after removing confounder, tokenHeader and HMAC
byte[] retVal = new byte[len];
System.arraycopy(temp, 0, retVal, 0, retVal.length);
return retVal;
return Arrays.copyOf(temp, len);
}
/**
......@@ -200,69 +120,26 @@ class WrapToken_v2 extends MessageToken_v2 {
public int getData(byte[] dataBuf, int dataBufOffset)
throws GSSException {
if (readTokenFromInputStream)
getDataFromStream(dataBuf, dataBufOffset);
else
getDataFromBuffer(dataBuf, dataBufOffset);
int retVal = 0;
if (privacy) {
retVal = dataSize - confounder.length -
TOKEN_HEADER_SIZE - cipherHelper.getChecksumLength();
} else {
retVal = dataSize - cipherHelper.getChecksumLength();
}
return retVal;
}
/**
* Helper routine to obtain the application data transmitted in
* this WrapToken. It is called if the WrapToken was constructed
* with a byte array as input.
* @param dataBuf the output buffer into which the data must be
* written
* @param dataBufOffset the offset at which to write the data
* @throws GSSException if an error occurs while decrypting any
* cipher text and checking for validity
*/
private void getDataFromBuffer(byte[] dataBuf, int dataBufOffset)
throws GSSException {
int dataPos = tokenOffset + TOKEN_HEADER_SIZE;
int data_length = 0;
if (dataPos + dataSize > tokenOffset + tokenLen)
throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1,
"Insufficient data in "
+ getTokenName(getTokenId()));
// debug("WrapToken cons: data is token is [" +
// getHexBytes(tokenBytes, tokenOffset, tokenLen) + "]\n");
confounder = new byte[CONFOUNDER_SIZE];
// Do decryption if this token was privacy protected.
if (privacy) {
// decrypt data
cipherHelper.decryptData(this, tokenBytes, dataPos, dataSize,
cipherHelper.decryptData(this, tokenData, 0, tokenDataLen,
dataBuf, dataBufOffset, getKeyUsage());
/*
debug("\t\tDecrypted data is [" +
getHexBytes(confounder) + " " +
getHexBytes(dataBuf, dataBufOffset,
dataSize - CONFOUNDER_SIZE) +
"]\n");
*/
data_length = dataSize - CONFOUNDER_SIZE -
TOKEN_HEADER_SIZE - cipherHelper.getChecksumLength();
return tokenDataLen - CONFOUNDER_SIZE -
TOKEN_HEADER_SIZE - cipherHelper.getChecksumLength();
} else {
// Token data is in cleartext
debug("\t\tNo encryption was performed by peer.\n");
// debug("\t\tNo encryption was performed by peer.\n");
// data
data_length = dataSize - cipherHelper.getChecksumLength();
System.arraycopy(tokenBytes, dataPos,
int data_length = tokenDataLen - cipherHelper.getChecksumLength();
System.arraycopy(tokenData, 0,
dataBuf, dataBufOffset,
data_length);
// debug("\t\tData is: " + getHexBytes(dataBuf, data_length));
......@@ -274,95 +151,26 @@ class WrapToken_v2 extends MessageToken_v2 {
throw new GSSException(GSSException.BAD_MIC, -1,
"Corrupt checksum in Wrap token");
}
return data_length;
}
}
/**
* Helper routine to obtain the application data transmitted in
* this WrapToken. It is called if the WrapToken was constructed
* with an Inputstream.
* @param dataBuf the output buffer into which the data must be
* written
* @param dataBufOffset the offset at which to write the data
* @throws GSSException if an error occurs while decrypting any
* cipher text and checking for validity
* Writes a WrapToken_v2 object
*/
private void getDataFromStream(byte[] dataBuf, int dataBufOffset)
throws GSSException {
int data_length = 0;
// Don't check the token length. Data will be read on demand from
// the InputStream.
// debug("WrapToken cons: data will be read from InputStream.\n");
confounder = new byte[CONFOUNDER_SIZE];
try {
// Do decryption if this token was privacy protected.
if (privacy) {
cipherHelper.decryptData(this, is, dataSize,
dataBuf, dataBufOffset, getKeyUsage());
/*
debug("\t\tDecrypted data is [" +
getHexBytes(confounder) + " " +
getHexBytes(dataBuf, dataBufOffset,
dataSize - CONFOUNDER_SIZE) +
"]\n");
*/
data_length = dataSize - CONFOUNDER_SIZE -
TOKEN_HEADER_SIZE - cipherHelper.getChecksumLength();
} else {
// Token data is in cleartext
debug("\t\tNo encryption was performed by peer.\n");
readFully(is, confounder);
// read the data
data_length = dataSize - cipherHelper.getChecksumLength();
readFully(is, dataBuf, dataBufOffset, data_length);
/*
* Make sure checksum is not corrupt
*/
if (!verifySign(dataBuf, dataBufOffset, data_length)) {
throw new GSSException(GSSException.BAD_MIC, -1,
"Corrupt checksum in Wrap token");
}
}
} catch (IOException e) {
throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1,
getTokenName(getTokenId())
+ ": " + e.getMessage());
}
}
public WrapToken_v2(Krb5Context context, MessageProp prop,
byte[] dataBytes, int dataOffset, int dataLen)
throws GSSException {
throws GSSException {
super(Krb5Token.WRAP_ID_v2, context);
confounder = Confounder.bytes(CONFOUNDER_SIZE);
dataSize = confounder.length + dataLen + TOKEN_HEADER_SIZE +
cipherHelper.getChecksumLength();
this.dataBytes = dataBytes;
this.dataOffset = dataOffset;
this.dataLen = dataLen;
// save initiator
this.initiator = context.isInitiator();
// debug("\nWrapToken cons: data to wrap is [" +
// getHexBytes(confounder) + " " +
// getHexBytes(dataBytes, dataOffset, dataLen) + "]\n");
genSignAndSeqNumber(prop,
dataBytes, dataOffset, dataLen);
genSignAndSeqNumber(prop, dataBytes, dataOffset, dataLen);
/*
* If the application decides to ask for privacy when the context
......@@ -374,110 +182,42 @@ class WrapToken_v2 extends MessageToken_v2 {
prop.setPrivacy(false);
privacy = prop.getPrivacy();
}
public void encode(OutputStream os) throws IOException, GSSException {
super.encode(os);
// debug("\n\nWriting data: [");
if (!privacy) {
// Wrap Tokens (without confidentiality) =
// { 16 byte token_header | plaintext | 12-byte HMAC }
// where HMAC is on { plaintext | token_header }
// calculate checksum
byte[] checksum = getChecksum(dataBytes, dataOffset, dataLen);
// data
// debug(" " + getHexBytes(dataBytes, dataOffset, dataLen));
os.write(dataBytes, dataOffset, dataLen);
// write HMAC
// debug(" " + getHexBytes(checksum,
// cipherHelper.getChecksumLength()));
os.write(checksum);
tokenData = new byte[dataLen + checksum.length];
System.arraycopy(dataBytes, dataOffset, tokenData, 0, dataLen);
System.arraycopy(checksum, 0, tokenData, dataLen, checksum.length);
} else {
// Wrap Tokens (with confidentiality) =
// { 16 byte token_header |
// Encrypt(16-byte confounder | plaintext | token_header) |
// 12-byte HMAC }
cipherHelper.encryptData(this, confounder, getTokenHeader(),
dataBytes, dataOffset, dataLen, getKeyUsage(), os);
tokenData = cipherHelper.encryptData(this, confounder, getTokenHeader(),
dataBytes, dataOffset, dataLen, getKeyUsage());
}
// debug("]\n");
}
public byte[] encode() throws IOException, GSSException {
// XXX Fine tune this initial size
ByteArrayOutputStream bos = new ByteArrayOutputStream(dataSize + 50);
encode(bos);
return bos.toByteArray();
public void encode(OutputStream os) throws IOException {
encodeHeader(os);
os.write(tokenData);
}
public int encode(byte[] outToken, int offset)
throws IOException, GSSException {
int retVal = 0;
// Token header is small
ByteArrayOutputStream bos = new ByteArrayOutputStream();
super.encode(bos);
byte[] header = bos.toByteArray();
System.arraycopy(header, 0, outToken, offset, header.length);
offset += header.length;
// debug("WrapToken.encode: Writing data: [");
if (!privacy) {
// Wrap Tokens (without confidentiality) =
// { 16 byte token_header | plaintext | 12-byte HMAC }
// where HMAC is on { plaintext | token_header }
// calculate checksum
byte[] checksum = getChecksum(dataBytes, dataOffset, dataLen);
// data
// debug(" " + getHexBytes(dataBytes, dataOffset, dataLen));
System.arraycopy(dataBytes, dataOffset, outToken, offset,
dataLen);
offset += dataLen;
// write HMAC
// debug(" " + getHexBytes(checksum,
// cipherHelper.getChecksumLength()));
System.arraycopy(checksum, 0, outToken, offset,
cipherHelper.getChecksumLength());
retVal = header.length + dataLen + cipherHelper.getChecksumLength();
} else {
// Wrap Tokens (with confidentiality) =
// { 16 byte token_header |
// Encrypt(16-byte confounder | plaintext | token_header) |
// 12-byte HMAC }
int cLen = cipherHelper.encryptData(this, confounder,
getTokenHeader(), dataBytes, dataOffset, dataLen,
outToken, offset, getKeyUsage());
retVal = header.length + cLen;
// debug(getHexBytes(outToken, offset, dataSize));
}
// debug("]\n");
// %%% assume that plaintext length == ciphertext len
return retVal;
public byte[] encode() throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream(
MessageToken_v2.TOKEN_HEADER_SIZE + tokenData.length);
encode(bos);
return bos.toByteArray();
}
protected int getKrb5TokenSize() throws GSSException {
return (getTokenSize() + dataSize);
public int encode(byte[] outToken, int offset) throws IOException {
byte[] token = encode();
System.arraycopy(token, 0, outToken, offset, token.length);
return token.length;
}
// This implementation is way to conservative. And it certainly
......@@ -485,6 +225,7 @@ class WrapToken_v2 extends MessageToken_v2 {
static int getSizeLimit(int qop, boolean confReq, int maxTokenSize,
CipherHelper ch) throws GSSException {
return (GSSHeader.getMaxMechTokenSize(OID, maxTokenSize) -
(getTokenSize(ch) + CONFOUNDER_SIZE) - 8 /* safety */);
(TOKEN_HEADER_SIZE + ch.getChecksumLength() + CONFOUNDER_SIZE)
- 8 /* safety */);
}
}
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,6 +25,34 @@
* @test
* @bug 6706974
* @summary Add krb5 test infrastructure
* @run main/othervm BasicKrb5Test
* @run main/othervm BasicKrb5Test des-cbc-crc
* @run main/othervm BasicKrb5Test des-cbc-md5
* @run main/othervm BasicKrb5Test des3-cbc-sha1
* @run main/othervm BasicKrb5Test aes128-cts
* @run main/othervm BasicKrb5Test aes256-cts
* @run main/othervm BasicKrb5Test rc4-hmac
* @run main/othervm BasicKrb5Test -s
* @run main/othervm BasicKrb5Test des-cbc-crc -s
* @run main/othervm BasicKrb5Test des-cbc-md5 -s
* @run main/othervm BasicKrb5Test des3-cbc-sha1 -s
* @run main/othervm BasicKrb5Test aes128-cts -s
* @run main/othervm BasicKrb5Test aes256-cts -s
* @run main/othervm BasicKrb5Test rc4-hmac -s
* @run main/othervm BasicKrb5Test -C
* @run main/othervm BasicKrb5Test des-cbc-crc -C
* @run main/othervm BasicKrb5Test des-cbc-md5 -C
* @run main/othervm BasicKrb5Test des3-cbc-sha1 -C
* @run main/othervm BasicKrb5Test aes128-cts -C
* @run main/othervm BasicKrb5Test aes256-cts -C
* @run main/othervm BasicKrb5Test rc4-hmac -C
* @run main/othervm BasicKrb5Test -s -C
* @run main/othervm BasicKrb5Test des-cbc-crc -s -C
* @run main/othervm BasicKrb5Test des-cbc-md5 -s -C
* @run main/othervm BasicKrb5Test des3-cbc-sha1 -s -C
* @run main/othervm BasicKrb5Test aes128-cts -s -C
* @run main/othervm BasicKrb5Test aes256-cts -s -C
* @run main/othervm BasicKrb5Test rc4-hmac -s -C
*/
import org.ietf.jgss.GSSName;
......@@ -39,6 +67,7 @@ import sun.security.krb5.internal.crypto.EType;
*/
public class BasicKrb5Test {
private static boolean conf = true;
/**
* @param args empty or etype
*/
......@@ -46,8 +75,10 @@ public class BasicKrb5Test {
throws Exception {
String etype = null;
if (args.length > 0) {
etype = args[0];
for (String arg: args) {
if (arg.equals("-s")) Context.usingStream = true;
else if(arg.equals("-C")) conf = false;
else etype = arg;
}
// Creates and starts the KDC. This line must be put ahead of etype check
......@@ -56,8 +87,9 @@ public class BasicKrb5Test {
System.out.println("Testing etype " + etype);
if (etype != null && !EType.isSupported(Config.getInstance().getType(etype))) {
// aes256 is not enabled on all systems
System.out.println("Not supported.");
System.exit(0);
return;
}
new BasicKrb5Test().go(OneKDC.SERVER, OneKDC.BACKEND);
......@@ -71,6 +103,7 @@ public class BasicKrb5Test {
c.startAsClient(server, GSSUtil.GSS_KRB5_MECH_OID);
c.x().requestCredDeleg(true);
c.x().requestConf(conf);
s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
c.status();
......@@ -90,6 +123,7 @@ public class BasicKrb5Test {
s = null;
s2.startAsClient(backend, GSSUtil.GSS_KRB5_MECH_OID);
s2.x().requestConf(conf);
b.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
s2.status();
......
/*
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -42,7 +42,8 @@ import org.ietf.jgss.Oid;
import com.sun.security.jgss.ExtendedGSSContext;
import com.sun.security.jgss.InquireType;
import com.sun.security.jgss.AuthorizationDataEntry;
import java.io.File;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
/**
* Context of a JGSS subject, encapsulating Subject and GSSContext.
......@@ -78,6 +79,8 @@ public class Context {
private String name;
private GSSCredential cred; // see static method delegated().
static boolean usingStream = false;
private Context() {}
/**
......@@ -365,7 +368,14 @@ public class Context {
public byte[] run(Context me, byte[] dummy) throws Exception {
System.out.println("wrap");
MessageProp p1 = new MessageProp(0, true);
byte[] out = me.x.wrap(messageBytes, 0, messageBytes.length, p1);
byte[] out;
if (usingStream) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
me.x.wrap(new ByteArrayInputStream(messageBytes), os, p1);
out = os.toByteArray();
} else {
out = me.x.wrap(messageBytes, 0, messageBytes.length, p1);
}
System.out.println(printProp(p1));
return out;
}
......@@ -375,27 +385,46 @@ public class Context {
@Override
public byte[] run(Context me, byte[] input) throws Exception {
MessageProp p1 = new MessageProp(0, true);
byte[] bytes = me.x.unwrap(input, 0, input.length, p1);
byte[] bytes;
if (usingStream) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
me.x.unwrap(new ByteArrayInputStream(input), os, p1);
bytes = os.toByteArray();
} else {
bytes = me.x.unwrap(input, 0, input.length, p1);
}
if (!Arrays.equals(messageBytes, bytes))
throw new Exception("wrap/unwrap mismatch");
System.out.println("unwrap");
System.out.println(printProp(p1));
p1 = new MessageProp(0, true);
System.out.println("getMIC");
bytes = me.x.getMIC(bytes, 0, bytes.length, p1);
if (usingStream) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
me.x.getMIC(new ByteArrayInputStream(messageBytes), os, p1);
bytes = os.toByteArray();
} else {
bytes = me.x.getMIC(messageBytes, 0, messageBytes.length, p1);
}
System.out.println(printProp(p1));
return bytes;
}
}, t);
// Re-unwrap should make p2.isDuplicateToken() returns true
s1.doAs(new Action() {
@Override
public byte[] run(Context me, byte[] input) throws Exception {
MessageProp p1 = new MessageProp(0, true);
System.out.println("verifyMIC");
me.x.verifyMIC(input, 0, input.length,
messageBytes, 0, messageBytes.length,
p1);
if (usingStream) {
me.x.verifyMIC(new ByteArrayInputStream(input),
new ByteArrayInputStream(messageBytes), p1);
} else {
me.x.verifyMIC(input, 0, input.length,
messageBytes, 0, messageBytes.length,
p1);
}
System.out.println(printProp(p1));
return null;
}
......@@ -416,7 +445,9 @@ public class Context {
sb.append(prop.isGapToken()?"gap, ":"");
sb.append(prop.isOldToken()?"old, ":"");
sb.append(prop.isUnseqToken()?"unseq, ":"");
sb.append(prop.getMinorString()+ "(" + prop.getMinorStatus()+")");
if (prop.getMinorStatus() != 0) {
sb.append(prop.getMinorString()+ "(" + prop.getMinorStatus()+")");
}
return sb.toString();
}
......@@ -442,7 +473,13 @@ public class Context {
return null;
} else {
System.out.println(c.name + " call initSecContext");
return me.x.initSecContext(input, 0, input.length);
if (usingStream) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
me.x.initSecContext(new ByteArrayInputStream(input), os);
return os.size() == 0 ? null : os.toByteArray();
} else {
return me.x.initSecContext(input, 0, input.length);
}
}
}
}, t);
......@@ -460,7 +497,13 @@ public class Context {
return null;
} else {
System.out.println(s.name + " called acceptSecContext");
return me.x.acceptSecContext(input, 0, input.length);
if (usingStream) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
me.x.acceptSecContext(new ByteArrayInputStream(input), os);
return os.size() == 0 ? null : os.toByteArray();
} else {
return me.x.acceptSecContext(input, 0, input.length);
}
}
}
}, t);
......
#
# Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# @test
# @bug 6706974
# @summary Add krb5 test infrastructure
# @run shell/timeout=300 basic.sh
#
if [ "${TESTSRC}" = "" ] ; then
TESTSRC="."
fi
if [ "${TESTJAVA}" = "" ] ; then
echo "TESTJAVA not set. Test cannot execute."
echo "FAILED!!!"
exit 1
fi
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
Windows_* )
FS="\\"
SEP=";"
;;
CYGWIN* )
FS="/"
SEP=";"
;;
* )
FS="/"
SEP=":"
;;
esac
${TESTJAVA}${FS}bin${FS}javac -XDignore.symbol.file -d . \
${TESTSRC}${FS}BasicKrb5Test.java \
${TESTSRC}${FS}KDC.java \
${TESTSRC}${FS}OneKDC.java \
${TESTSRC}${FS}Action.java \
${TESTSRC}${FS}Context.java \
|| exit 10
# Add $TESTSRC to classpath so that customized nameservice can be used
J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. BasicKrb5Test"
$J || exit 100
$J des-cbc-crc || exit 1
$J des-cbc-md5 || exit 3
$J des3-cbc-sha1 || exit 16
$J aes128-cts || exit 17
$J aes256-cts || exit 18
$J rc4-hmac || exit 23
exit 0
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册