📄 pgpx509keys.c
字号:
CHKASNERR( err );
/* prime p */
bnbuf[0] = dssp->p.val;
bnlen[0] = dssp->p.len;
err = sDecodeX509Integer (bnbuf[0], bnlen[0], NULL, &bnlength[0]);
if( IsPGPError( err ) )
goto error;
/* subprime q */
bnbuf[1] = dssp->q.val;
bnlen[1] = dssp->q.len;
err = sDecodeX509Integer (bnbuf[1], bnlen[1], NULL, &bnlength[1]);
if( IsPGPError( err ) )
goto error;
/* generator g */
bnbuf[2] = dssp->g.val;
bnlen[2] = dssp->g.len;
err = sDecodeX509Integer (bnbuf[2], bnlen[2], NULL, &bnlength[2]);
if( IsPGPError( err ) )
goto error;
/* public value y */
bnbuf[3] = dssk->val;
bnlen[3] = dssk->len;
err = sDecodeX509Integer (bnbuf[3], bnlen[3], NULL, &bnlength[3]);
if( IsPGPError( err ) )
goto error;
pubelems = 4;
} else if (keyalgorithm == kPGPPublicKeyAlgorithm_ElGamal) {
pgpasn_UnpackELGParms ( asnctx, &elgp,
spki->algorithm.parameters->val,
spki->algorithm.parameters->len, &err );
CHKASNERR( err );
pgpasn_UnpackELGPublicKey ( asnctx, &elgk,
spki->subjectPublicKey.val,
spki->subjectPublicKey.len, &err );
CHKASNERR( err );
/* prime p */
bnbuf[0] = elgp->p.val;
bnlen[0] = elgp->p.len;
err = sDecodeX509Integer (bnbuf[0], bnlen[0], NULL, &bnlength[0]);
if( IsPGPError( err ) )
goto error;
/* generator g */
bnbuf[1] = elgp->g.val;
bnlen[1] = elgp->g.len;
err = sDecodeX509Integer (bnbuf[1], bnlen[1], NULL, &bnlength[1]);
if( IsPGPError( err ) )
goto error;
/* public value y */
bnbuf[2] = elgk->val;
bnlen[2] = elgk->len;
err = sDecodeX509Integer (bnbuf[2], bnlen[2], NULL, &bnlength[2]);
if( IsPGPError( err ) )
goto error;
pubelems = 3;
} else /* RSA */ {
pgpasn_UnpackRSAKey ( asnctx, &rsak, spki->subjectPublicKey.val,
spki->subjectPublicKey.len, &err );
CHKASNERR( err );
/* modulus n */
bnbuf[0] = rsak->modulus.val;
bnlen[0] = rsak->modulus.len;
err = sDecodeX509Integer (bnbuf[0], bnlen[0], NULL, &bnlength[0]);
if( IsPGPError( err ) )
goto error;
/* exponent e */
bnbuf[1] = rsak->exponent.val;
bnlen[1] = rsak->exponent.len;
err = sDecodeX509Integer (bnbuf[1], bnlen[1], NULL, &bnlength[1]);
if( IsPGPError( err ) )
goto error;
pubelems = 2;
}
}
keybuflength = 0;
publength = 0;
for (i=0; i<elemsof(bnlength); ++i) {
if( bnlength[i] == 0 )
break;
if (i < pubelems)
publength += bnlength[i];
keybuflength += bnlength[i];
}
/*
* To better estimate keybuflength, we need to construct the numeric
* data portion and then see if it matches an incoming key. Only then
* can we know what kind of key packet we are dealing with.
*/
pubbuf = PGPNewData (mgr, publength, 0);
CHKNONNULL(pubbuf, err);
o = 0;
for (i=0; i<pubelems; ++i) {
if( bnlength[i] == 0 )
break;
err = sDecodeX509Integer (bnbuf[i], bnlen[i],
pubbuf+o, &bnlength[i]);
if( IsPGPError( err ) )
goto error;
o += bnlength[i];
}
pgpAssert (o == publength);
/* Get hash of numeric data */
pgpFingerprint20HashBuf (context, pubbuf, publength, hash20);
/* See if this matches an existing key */
matchkey = NULL;
if( IsntNull( refdb ) )
{
matchkey = pgpKeyDBFindKey20n (refdb, hash20);
} else {
refdb = pgpContextGetFirstKeyDB(context);
while( IsntNull( refdb ) && IsNull( matchkey ) )
{
matchkey = pgpKeyDBFindKey20n (refdb, hash20);
refdb = pgpKeyDBNextKeyDB( refdb );
}
}
if( IsNull( matchkey ) ) {
/* Fall back on defaults */
if (keyalgorithm == kPGPPublicKeyAlgorithm_RSA)
keyversion = PGPVERSION_3;
else
keyversion = PGPVERSION_4;
} else {
PGPSize hlen;
matchkeybuf = pgpFetchObject (matchkey, &matchkeybuflength);
if( IsNull( matchkeybuf ) ) {
err = pgpKeyDBError(PGPPeekKeyDBObjKeyDB(matchkey));
goto error;
}
hlen = pgpPktBufferHeaderLen( matchkeybuf );
matchkeybuf += hlen;
matchkeybuflength -= hlen;
keyversion = matchkeybuf[0];
}
keybuflength += 6; /* bytes preceding bignums */
if( keyversion <= PGPVERSION_3)
keybuflength += 2; /* room for expiration date */
if( IsntNull( pinfo ) ) {
/*
* Can only import private if we have a matching key,
* because we can't synthesize a userid for it
*/
if( IsNull( matchkey ) ) {
err = kPGPError_PublicKeyNotFound;
goto error;
}
keybuflength += 3; /* Private adds 1 enc byte + 2 csum */
}
if( IsNull( keyBuf ) ) {
*keyLength = keybuflength;
} else {
pgpAssert (*keyLength == keybuflength);
/* public key packet */
o = 0;
keyBuf[o++] = keyversion;
/* 1-4 are timestamp */
if (IsntNull( matchkey ) ) {
pgpCopyMemory (matchkeybuf+1, keyBuf+o, 4);
} else {
PGPUInt32 creation = sDecodeKeyCreation( asnctx, cert );
if( creation != 0 ) {
keyBuf[o+0] = (creation >> 24) & 0xff;
keyBuf[o+1] = (creation >> 16) & 0xff;
keyBuf[o+2] = (creation >> 8) & 0xff;
keyBuf[o+3] = (creation >> 0) & 0xff;
} else {
/* Use certificate creation date if all else fails */
err = sDecodeNotBefore4( asnctx, cert, keyBuf+o );
if (IsPGPError( err ) ) {
pgpClearMemory (keyBuf+o, 4);
err = kPGPError_NoErr;
}
}
}
o += 4;
/* Next two are expiration if V3 packets */
if (keyversion <= PGPVERSION_3) {
if (IsntNull( matchkey ) ) {
pgpCopyMemory (matchkeybuf+5, keyBuf+o, 2);
} else {
pgpClearMemory (keyBuf+o, 2);
}
o += 2;
}
keyBuf[o++] = keyalgorithm;
pgpCopyMemory (pubbuf, keyBuf+o, publength);
o += publength;
PGPFreeData( pubbuf );
pubbuf = NULL;
if( IsntNull( pinfo ) ) {
/* Save secret key fields */
keyBuf[o++] = '\0'; /* Unencrypted secret data */
checksum = 0;
for (i=pubelems; i<elemsof(bnlength); ++i) {
if( bnlength[i] == 0 )
break;
err = sDecodeX509Integer (bnbuf[i], bnlen[i],
keyBuf+o, &bnlength[i]);
if( IsPGPError( err ) )
goto error;
for (j=0; j<bnlength[i]; ++j)
checksum += keyBuf[o+j];
o += bnlength[i];
}
keyBuf[o++] = (checksum >> 8) & 0xff;
keyBuf[o++] = (checksum >> 0) & 0xff;
}
pgpAssert (o == keybuflength);
}
error:
if( IsntNull( pubbuf ) )
PGPFreeData( pubbuf );
if( IsntNull( dssp ) )
pgpasn_FreeDssParms( asnctx, dssp );
if( IsntNull( dssk ) )
pgpasn_FreeDSAPublicKey( asnctx, dssk );
if( IsntNull( elgp ) )
pgpasn_FreeELGParms( asnctx, elgp );
if( IsntNull( elgk ) )
pgpasn_FreeELGPublicKey( asnctx, elgk );
if( IsntNull( rsak ) )
pgpasn_FreeRSAKey( asnctx, rsak );
if( IsntNull( rsapriv ) )
pgpasn_FreeRSAPrivateKey( asnctx, rsapriv );
return err;
}
/*
* Given an X509 cert, return a PGPKeyDBRef containing a single PGP key
* with the same key material as the original cert. The userid on the
* key is one of the 509 subject distinguished name fields, the common name
* if it exists, else one of the other fields.
*/
static PGPError
sDecode509(PGPContextRef context, PGPASN_CONTEXT *asnctx,
PGPASN_Certificate *cert, PGPKeyDBRef refdb, PGPKeyDBRef *keydb)
{
PGPMemoryMgrRef mgr;
PGPByte *pgpkeybuf = NULL;
PGPSize keylen;
PGPSize namelen;
PGPSize siglen;
PGPSize pgpkeylen;
PGPUInt32 o;
PGPKeyDBRef kdb;
PGPError err = kPGPError_NoErr;
*keydb = NULL;
mgr = PGPPeekContextMemoryMgr( context );
/* Decode signature packet */
err = sDecodeSig (context, asnctx, cert, SIGSUBSUB_X509_VERSION_LO,
NULL, &siglen);
if (IsPGPError(err))
goto error;
/* Decode subject name */
err = sDecodeName (asnctx, cert, FALSE, NULL, &namelen);
if (IsPGPError(err))
goto error;
/* Decode key packet */
err = sDecodeKey (context, refdb, asnctx, cert, NULL, NULL, &keylen);
if (IsPGPError(err))
goto error;
/* Now create the PGP key */
pgpkeylen = 3 + keylen + 2 + (namelen>255) + namelen
+ ((siglen>0)?(3+siglen):0);
pgpkeybuf = (PGPByte *) PGPNewData( mgr, pgpkeylen, 0 );
CHKNONNULL (pgpkeybuf, err);
/* public key packet */
o = 0;
pgpkeybuf[o++] = PKTBYTE_BUILD(PKTBYTE_PUBKEY, 1),
pgpkeybuf[o++] = (keylen >> 8) & 0xff;
pgpkeybuf[o++] = (keylen >> 0) & 0xff;
err = sDecodeKey (context, refdb, asnctx, cert, NULL, pgpkeybuf + o,
&keylen);
if (IsPGPError(err))
goto error;
o += keylen;
/* userid packet */
if( namelen > 255 )
{
pgpAssert( namelen < 0x10000 );
pgpkeybuf[o++] = PKTBYTE_BUILD(PKTBYTE_USERID, 1);
pgpkeybuf[o++] = (namelen >> 8) & 0xff;
pgpkeybuf[o++] = (namelen >> 0) & 0xff;
} else {
pgpkeybuf[o++] = PKTBYTE_BUILD(PKTBYTE_USERID, 0);
pgpkeybuf[o++] = (PGPByte)namelen;
}
err = sDecodeName (asnctx, cert, FALSE, pgpkeybuf + o, &namelen);
if (IsPGPError(err))
goto error;
o += namelen;
/* sig packet */
pgpkeybuf[o++] = PKTBYTE_BUILD(PKTBYTE_SIG, 1);
pgpkeybuf[o++] = (siglen >> 8) & 0xff;
pgpkeybuf[o++] = (siglen >> 0) & 0xff;
err = sDecodeSig (context, asnctx, cert, SIGSUBSUB_X509_VERSION_LO,
pgpkeybuf + o, &siglen);
if (IsPGPError(err))
goto error;
o += siglen;
pgpAssert (o == pgpkeylen);
err = pgpImportKeyBinary( context, pgpkeybuf, pgpkeylen, &kdb );
if( IsPGPError( err ) )
goto error;
*keydb = kdb;
/* Fall through */
error:
if( IsntNull(pgpkeybuf) )
PGPFreeData( pgpkeybuf );
return err;
}
/* Entry point to import a 509 cert from the specified location */
PGPError
pgpDecodeX509Cert( PGPByte *buf, PGPSize len, PGPContextRef context,
PGPKeyDBRef refdb, PGPKeyDBRef *keydb )
{
PGPASN_Certificate *cert;
PGPMemoryMgrRef mgr;
PGPASN_CONTEXT asnctx_static, *asnctx = &asnctx_static;
PGPASN_MemoryMgr asnmem;
PGPError err = kPGPError_NoErr;
mgr = PGPPeekContextMemoryMgr( context );
sSetupASNCONTEXT (mgr, asnctx, &asnmem);
pgpasn_UnpackCertificate( asnctx, &cert, buf, len, &err );
CHKASNERR( err )
err = sDecode509( context, asnctx, cert, refdb, keydb);
pgpasn_FreeCertificate( asnctx, cert );
error:
return err;
}
/* Entry point to import a SET OF X509 certs */
PGPError
pgpDecodeX509CertSet(PGPByte *buf, PGPSize len, PGPContextRef context,
PGPKeyDBRef refdb, PGPKeyDBRef *keydb)
{
PGPASN_Certificates *certs = NULL;
PGPASN_Certificate *cert;
PGPMemoryMgrRef mgr;
PGPASN_CONTEXT asnctx_static, *asnctx = &asnctx_static;
PGPASN_MemoryMgr asnmem;
PGPKeyDBRef newkdb = NULL;
PGPKeyDBRef tmpkdb = NULL;
PGPInt32 i;
PGPError err = kPGPError_NoErr;
mgr = PGPPeekContextMemoryMgr( context );
sSetupASNCONTEXT (mgr, asnctx, &asnmem);
pgpAssert( IsntNull( keydb ) );
*keydb = NULL;
if( IsPGPError( err = PGPNewKeyDB( context, &newkdb ) ) )
goto error;
pgpasn_UnpackCertificates( asnctx, &certs, buf, len, &err );
CHKASNERR( err );
for (i=0; i<certs->n; ++i) {
cert = certs->elt[i];
err = sDecode509( context, asnctx, cert, refdb, &tmpkdb );
CHKASNERR( err );
PGPCopyKeys( pgpKeyDBPeekRootSet(tmpkdb), newkdb, NULL );
PGPFreeKeyDB( tmpkdb );
tmpkdb = NULL;
}
error:
if( IsntNull( certs ) )
pgpasn_FreeCertificates( asnctx, certs );
if( IsntNull( tmpkdb ) )
PGPFreeKeyDB( tmpkdb );
if( IsntPGPError( err ) )
*keydb = newkdb;
else if( IsntNull( newkdb ) )
PGPFreeKeyDB( newkdb );
return err;
}
/* Entry point to import a SET OF X509 CRLs. Creates a new keydb. */
PGPError
pgpDecodeX509CRLSet( PGPByte *buf, PGPSize len, PGPContextRef context,
PGPKeyDBRef refdb, PGPKeyDBRef *keydb )
{
PGPASN_CertificateRevocationLists *crls = NULL;
PGPASN_CertificateRevocationList *crl;
PGPASN_Extension *ext;
PGPASN_DistributionPointName *dpname;
PGPASN_GeneralNames *gnames;
PGPASN_IssuingDistributionPoint *dpt = NULL;
PGPMemoryMgrRef mgr;
PGPASN_CONTEXT asnctx_static, *asnctx = &asnctx_static;
PGPASN_MemoryMgr asnmem;
PGPPubKey *pubkey = NULL;
PGPByte *pgpcrlbuf = NULL;
PGPByte *pgpcrlbufptr;
PGPSize pgpcrllen;
PGPSize pgpcrlbuflen;
PGPSize pgpcrlheaderlen;
PGPByte *crlbuf = NULL;
PGPSize crllen;
PGPKeyDBRef newkdb = NULL;
PGPKeyDBObj *crlkey = NULL;
PGPByte *namebuf = NULL;
PGPSize namebuflen;
PGPByte *dpoint = NULL; /* Dynamically allocated */
PGPByte const *keybuf, *keynamebuf;
PGPSize keybuflen, keynamebuflen;
PGPByte pkttype;
PGPSize dpointlen;
PGPInt32 j;
PGPError err = kPGPError_NoErr;
pgpAssert( IsntNull( keydb ) );
*keydb = NULL;
mgr = PGPPeekContextMemoryMgr( context );
sSetupASNCONTEXT (mgr, asnctx, &asnmem);
pgpasn_UnpackCertificateRevocationLists( asnctx, &crls, buf, len, &err );
CHKASNERR( err );
/* Only use first CRL because we must create a new keydb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -