Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
sources/ASIPChallenge.cp
// ASIPChallenge.cp - base class for Appleshare IP Challenge Object |
// |
// Apple Macintosh Developer Technical Support |
// Written by: Vinnie Moscaritolo |
// |
// Copyright (work in progress) Apple Computer, Inc All rights reserved. |
// |
// You may incorporate this sample code into your applications without |
// restriction, though the sample code has been provided "AS IS" and the |
// responsibility for its operation is 100% yours. However, what you are |
// not permitted to do is to redistribute the source as "DSC Sample Code" |
// after having made changes. If you're going to re-distribute the source, |
// we require that you make it clear in the source that the code was |
// descended from Apple Sample Code, but that you've made changes. |
// |
#include <string.h> |
#include <TextUtils.h> |
#include <PLStringFuncs.h> |
#include "ASIPChallenge.h" |
#include "PassphraseCache.h" |
#include "TPGPException.h" |
#include "pgpRandomPool.h" |
#include "pgpUserInterface.h" |
// --------------------------------------------------------------------------- |
void MakeChallenge(TPGPkey *theKey, StringPtr outBuf) |
// --------------------------------------------------------------------------- |
// |
// outBuf --> [len][challenge] |
{ |
PGPSize challengeSize; |
PGPError err; |
challengeSize = theKey->GetHashSize(); |
while ((err = PGPContextGetRandomBytes(TPGPkey::fgContext, &outBuf[1], challengeSize)) == kPGPError_OutOfEntropy ) |
{ |
// handle entropy errors? |
// what about no UI? |
ThrowIfPGPErr( |
PGPCollectRandomDataDialog(TPGPkey::fgContext, |
PGPGlobalRandomPoolGetMinimumEntropy() - PGPGlobalRandomPoolGetEntropy(), |
PGPOLastOption(TPGPkey::fgContext ))); |
} |
ThrowIfPGPErr(err); |
outBuf[0] = challengeSize & 0xFF; |
} |
#define counterChallengeSize 64 |
// --------------------------------------------------------------------------- |
void ReplyToChallenge(TPGPkey *serverKey, const char *passPhrase, TPGPkey *clientKey, StringPtr inBuf, StringPtr outBuf) |
// --------------------------------------------------------------------------- |
// |
// inBuf --> [len][challenge] |
// |
// outBuf <-- [len of total][offset to orig challenge][counterchallenge] [sig] |
{ |
UInt8 *counterChallenge = (UInt8*) outBuf + 1; |
UInt8 offset; |
PGPSize sigBufSize = 0; |
ThrowPGPErrIfTrue( clientKey->GetHashSize() * 2 > counterChallengeSize , kPGPError_BufferTooSmall); |
// calculate counter challenge string |
PGPContextGetRandomBytes(TPGPkey::fgContext, counterChallenge, counterChallengeSize ); |
// offset the challenge into the counterchallenge |
offset = counterChallengeSize - inBuf[0] - (counterChallenge[0] & 0x1F); |
ThrowPGPErrIfTrue ( offset < 1, kPGPError_BufferTooSmall); |
counterChallenge[0] = offset; |
memcpy(&counterChallenge[offset], inBuf+1, inBuf[0]); |
// sign the counter challenge |
if(serverKey && serverKey->CanSign() ) |
serverKey->Sign(counterChallenge, counterChallengeSize , counterChallenge + counterChallengeSize, &sigBufSize, passPhrase); |
outBuf[0] = (sigBufSize & 0xFF) + 64; |
} |
// --------------------------------------------------------------------------- |
Boolean VerifyChallenge(TPGPkey *theKey,StringPtr origChallenge, StringPtr inBuf) |
// --------------------------------------------------------------------------- |
// |
// origChallenge <-- [len][challenge] |
// inBuf <-- [len of total][offset to orig challenge][counterchallenge] [sig] |
// |
{ |
// check if challenge string is correct. |
if(!(memcmp( &inBuf[ inBuf[1] + 1] , &origChallenge[1], origChallenge[0]) == 0 )) |
return false; |
// check sig |
return theKey->Verify( &inBuf[1], 64, &inBuf[65], inBuf[0] - 64); |
} |
// --------------------------------------------------------------------------- |
PGPError ReplyToCounterChallenge(StringPtr promptString, StringPtr fpBuf, StringPtr inBuf, StringPtr outBuf) |
// --------------------------------------------------------------------------- |
// |
// fpBuf <-- [len][fingerprint of challenged] |
// inBuf <-- [len of total][offset to orig challenge][counterchallenge] [sig] |
// outbuf --> [len of sig] [sig] |
// |
// |
{ |
PGPFilterRef theFilter = kInvalidPGPFilterRef; |
PGPKeyIterRef theIterator = kInvalidPGPKeyIterRef; |
PGPKeyListRef theKeyListRef = kInvalidPGPKeyListRef; |
PGPKeyRef theKeyRef = kInvalidPGPKeyRef; |
PGPOptionListRef optionList = kInvalidPGPOptionListRef; |
PGPContextRef context = TPGPkey::fgContext; |
PGPKeySetRef newKeySet = NULL; |
PGPUInt32 numKeys; |
PGPError err = noErr; |
// Find key in database |
ThrowIfPGPErr( PGPNewKeyFingerPrintFilter(TPGPkey::fgContext,&fpBuf[1],fpBuf[0] , &theFilter)); |
ThrowIfPGPErr( PGPFilterKeySet(TPGPkey::fgPGPKeySetRef , theFilter, &newKeySet)); |
PGPFreeFilter(theFilter); |
ThrowIfPGPErr( PGPCountKeys(newKeySet, &numKeys)); |
if(numKeys != 1) |
err = kPGPError_KeyInvalid; |
else |
{ |
unsigned char promptStr[256]; |
char *thePassphrase = NULL; |
ThrowIfPGPErr( PGPOrderKeySet(newKeySet,kPGPAnyOrdering, &theKeyListRef)); |
ThrowIfPGPErr( PGPNewKeyIter( theKeyListRef, &theIterator )); |
ThrowIfPGPErr( PGPKeyIterNext( theIterator, &theKeyRef )); |
ThrowIfPGPErr ( PGPBuildOptionList( context, &optionList, |
PGPOUIOutputPassphrase(context, &thePassphrase), |
PGPOUIDefaultKey(context, theKeyRef), |
PGPOUIVerifyPassphrase(context, true), |
PGPOLastOption(context) )); |
if(promptString) |
{ |
ThrowIfPGPErr ( PGPAppendOptionList( optionList, |
PGPOUIDialogPrompt(context, (char *)promptString), |
PGPOLastOption(context) )); |
}; |
if( GetPassphrase(TPGPkey::fgContext, theKeyRef, &thePassphrase) |
|| ( (err = PGPSigningPassphraseDialog(context, newKeySet, &theKeyRef, |
optionList, |
PGPOLastOption(TPGPkey::fgContext ))) == kPGPError_NoErr ) |
&& (RememberPassphrase(theKeyRef, thePassphrase), true)) |
{ |
TPGPkey theKey; |
PGPSize sigBufSize; |
theKey.Initialize(theKeyRef); |
if( theKey.IsOperational()) |
{ |
if( ! theKey.Sign(&inBuf[1], 64, &outBuf[1], &sigBufSize, thePassphrase)) |
err = kPGPError_KeyInvalid; |
outBuf[0] = (sigBufSize & 0xFF); |
} |
// Erase passphrase |
PGPFreeData(thePassphrase); |
thePassphrase = NULL; |
} |
if(err == kPGPError_UserAbort) err = userCanceledErr; |
} |
PGPFreeOptionList(optionList); |
PGPFreeKeyIter(theIterator ); |
PGPFreeKeyList(theKeyListRef ); |
PGPFreeKeySet(newKeySet ); |
return err; |
} |
// --------------------------------------------------------------------------- |
Boolean VerifyCounterChallenge(TPGPkey *theKey, StringPtr origCounterChallenge, StringPtr inBuf) |
// --------------------------------------------------------------------------- |
// |
// origCounterChallenge <-- [len of total][offset to orig challenge][counterchallenge] [sig] |
// inBuf <-- [len of sig] [sig] |
{ |
return theKey->Verify( &origCounterChallenge[1], 64, &inBuf[1], inBuf[0]); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-22