diff --git a/src/steamnetworkingsockets/steamnetworkingsockets_certs.cpp b/src/steamnetworkingsockets/steamnetworkingsockets_certs.cpp index f4feec0..596596f 100644 --- a/src/steamnetworkingsockets/steamnetworkingsockets_certs.cpp +++ b/src/steamnetworkingsockets/steamnetworkingsockets_certs.cpp @@ -9,19 +9,28 @@ namespace SteamNetworkingSocketsLib { +uint64 CalculatePublicKeyID_Ed25519( const void *pPubKey, size_t cbPubKey ) +{ + if ( cbPubKey != 32 ) + return 0; + + SHA256Digest_t digest; + CCrypto::GenerateSHA256Digest( pPubKey, cbPubKey, &digest ); + + // First 8 bytes + return LittleQWord( *(uint64*)&digest ); +} + uint64 CalculatePublicKeyID( const CECSigningPublicKey &pubKey ) { if ( !pubKey.IsValid() ) return 0; // SHA over the whole public key. - SHA256Digest_t digest; uint8 data[32]; - DbgVerify( pubKey.GetRawData( data ) == sizeof(data) ); - CCrypto::GenerateSHA256Digest( data, sizeof(data), &digest ); - - // First 8 bytes - return LittleQWord( *(uint64*)&digest ); + uint32 cbPubKey = pubKey.GetRawData( data ); + Assert( cbPubKey == sizeof(data) ); + return CalculatePublicKeyID_Ed25519( data, cbPubKey ); } // Returns: diff --git a/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp b/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp index 3671439..16c8952 100644 --- a/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp +++ b/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp @@ -244,7 +244,7 @@ struct PublicKey if ( m_eTrust >= k_ETrust_Trusted ) return true; Assert( m_eTrust <= k_ETrust_NotTrusted ); - Assert( !m_status_msg.empty() ); // We should nkow the reason for any key we don't trust + Assert( !m_status_msg.empty() ); // We should know the reason for any key we don't trust return false; } @@ -666,6 +666,38 @@ const CertAuthScope *CertStore_CheckCert( const CMsgSteamDatagramCertificateSign return nullptr; } + // Check if their key has specifically been revoked. + if ( outMsgCert.key_type() != CMsgSteamDatagramCertificate_EKeyType_ED25519 ) + { + V_sprintf_safe( errMsg, "Cert has invalid key type %d", (int)outMsgCert.key_type() ); + return nullptr; + } + uint64 nKeyID = CalculatePublicKeyID_Ed25519( outMsgCert.key_data().c_str(), outMsgCert.key_data().length() ); + if ( nKeyID == 0) + { + V_sprintf_safe( errMsg, "Cert has invalid public key" ); + return nullptr; + } + const PublicKey *pPubKey = FindPublicKey( nKeyID ); + if ( pPubKey ) + { + if ( pPubKey->m_eTrust == k_ETrust_NotTrusted ) + { + // Hm - this status doesn't mean "bad", it just means that the cert in the cert store + // with this key was not able to be verified. This is an an unusual situation, ordinarily + // we should not have any certs in the cert store that we are not able to trust. Still, we + // just specific ally verified trust above. So let's continue on, but without adding this + // to the cert store. + } + else if ( !pPubKey->IsTrusted() ) + { + // Key is revoked. + Assert( pPubKey->m_eTrust == k_ETrust_Revoked ); + V_sprintf_safe( errMsg, "Cert has untrusted public key. %s", pPubKey->m_status_msg.c_str() ); + return nullptr; + } + } + return pResult; } @@ -677,7 +709,7 @@ bool CheckCertAppID( const CMsgSteamDatagramCertificate &msgCert, const CertAuth { if ( !pCACertAuthScope || pCACertAuthScope->m_apps.HasItem( nAppID ) ) return true; - V_sprintf_safe( errMsg, "Cert is not restricted by appid, by CA trust chain is, and does not authorize %u", nAppID ); + V_sprintf_safe( errMsg, "Cert is not restricted by appid, but CA trust chain is, and does not authorize %u", nAppID ); return true; } @@ -713,7 +745,7 @@ bool CheckCertPOPID( const CMsgSteamDatagramCertificate &msgCert, const CertAuth { if ( !pCACertAuthScope || pCACertAuthScope->m_pops.HasItem( popID ) ) return true; - V_sprintf_safe( errMsg, "Cert is not restricted by POPID, by CA trust chain is, and does not authorize %s", SteamNetworkingPOPIDRender( popID ).c_str() ); + V_sprintf_safe( errMsg, "Cert is not restricted by POPID, but CA trust chain is, and does not authorize %s", SteamNetworkingPOPIDRender( popID ).c_str() ); return true; } diff --git a/src/steamnetworkingsockets/steamnetworkingsockets_internal.h b/src/steamnetworkingsockets/steamnetworkingsockets_internal.h index 3989cd0..7bc7b98 100644 --- a/src/steamnetworkingsockets/steamnetworkingsockets_internal.h +++ b/src/steamnetworkingsockets/steamnetworkingsockets_internal.h @@ -442,6 +442,7 @@ extern uint32 Murmorhash32( const void *data, size_t len ); /// although not really cryptographically secure. (We are in charge of the /// set of public keys and we expect it to be reasonably small.) extern uint64 CalculatePublicKeyID( const CECSigningPublicKey &pubKey ); +extern uint64 CalculatePublicKeyID_Ed25519( const void *pPubKey, size_t cbPubKey ); /// Check an arbitrary signature using the specified public key. (It's assumed that you have /// already verified that this public key is from somebody you trust.)