/////////////////////////////////////////////////////////////////////////////
// Deterministically generate new public key using a chaincode
SecureBinaryData CryptoECDSA::ComputeChainedPublicKey(
                                SecureBinaryData const & binPubKey,
                                SecureBinaryData const & chainCode,
                                SecureBinaryData* multiplierOut)
{
   if(CRYPTO_DEBUG)
   {
      cout << "ComputeChainedPUBLICKey:" << endl;
      cout << "   BinPub: " << binPubKey.toHexStr() << endl;
      cout << "   BinChn: " << chainCode.toHexStr() << endl;
   }
   static SecureBinaryData SECP256K1_ORDER_BE = SecureBinaryData::CreateFromHex(
           "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");

   // Added extra entropy to chaincode by xor'ing with hash256 of pubkey
   BinaryData chainMod  = binPubKey.getHash256();
   BinaryData chainOrig = chainCode.getRawCopy();
   BinaryData chainXor(32);
      
   for(uint8_t i=0; i<8; i++)
   {
      uint8_t offset = 4*i;
      *(uint32_t*)(chainXor.getPtr()+offset) =
                           *(uint32_t*)( chainMod.getPtr()+offset) ^ 
                           *(uint32_t*)(chainOrig.getPtr()+offset);
   }

   // Parse the chaincode as a big-endian integer
   CryptoPP::Integer mult;
   mult.Decode(chainXor.getPtr(), chainXor.getSize(), UNSIGNED);

   // "new" init as "old", to make sure it's initialized on the correct curve
   BTC_PUBKEY oldPubKey = ParsePublicKey(binPubKey); 
   BTC_PUBKEY newPubKey = ParsePublicKey(binPubKey);

   // Let Crypto++ do the EC math for us, serialize the new public key
   newPubKey.SetPublicElement( oldPubKey.ExponentiatePublicElement(mult) );

   if(multiplierOut != NULL)
      (*multiplierOut) = SecureBinaryData(chainXor);

   //LOGINFO << "Computed new chained public key using:";
   //LOGINFO << "   Public key: " << binPubKey.toHexStr().c_str();
   //LOGINFO << "   PubKeyHash: " << chainMod.toHexStr().c_str();
   //LOGINFO << "   Chaincode:  " << chainOrig.toHexStr().c_str();
   //LOGINFO << "   Multiplier: " << chainXor.toHexStr().c_str();

   return CryptoECDSA::SerializePublicKey(newPubKey);
}
bool CryptoECDSA::CheckPubPrivKeyMatch(SecureBinaryData const & privKey32,
                                       SecureBinaryData const & pubKey65)
{
   if(CRYPTO_DEBUG)
   {
      cout << "CheckPubPrivKeyMatch:" << endl;
      cout << "   BinPrv: " << privKey32.toHexStr() << endl;
      cout << "   BinPub: " << pubKey65.toHexStr() << endl;
   }

   BTC_PRIVKEY privKey = ParsePrivateKey(privKey32);
   BTC_PUBKEY  pubKey  = ParsePublicKey(pubKey65);
   return CheckPubPrivKeyMatch(privKey, pubKey);
}
bool CryptoECDSA::VerifyData(SecureBinaryData const & binMessage, 
                             SecureBinaryData const & binSignature,
                             SecureBinaryData const & pubkey65B)
{
   if(CRYPTO_DEBUG)
   {
      cout << "VerifyData:" << endl;
      cout << "   BinMsg: " << binMessage.toHexStr() << endl;
      cout << "   BinSig: " << binSignature.toHexStr() << endl;
      cout << "   BinPub: " << pubkey65B.toHexStr() << endl;
   }

   BTC_PUBKEY cppPubKey = ParsePublicKey(pubkey65B);
   return VerifyData(binMessage, binSignature, cppPubKey);
}
BTC_PUBKEY CryptoECDSA::ParsePublicKey(SecureBinaryData const & pubKey65B)
{
   SecureBinaryData pubXbin(pubKey65B.getSliceRef( 1,32));
   SecureBinaryData pubYbin(pubKey65B.getSliceRef(33,32));
   return ParsePublicKey(pubXbin, pubYbin);
}
示例#5
0
/**
 * Main function.
 *
 * Checks certificate and certificate revocation list
 *
 * @param[in]  argc An integer argument count of the command line arguments
 * @param[in]  argv An argument vector of the command line arguments
 *
 * @return[out] an integer 0 upon exit success
 */
int main(int argc, char *argv[])
{
    int isCrt = 0;
    const char *testedFileName = 0;
    const char *caCrtFileName = 0;

    // Parse command line arguments
    int opt;

    while ((opt = getopt(argc, argv, "c:f:s:")) != -1)
    {
        switch (opt)
        {
            case 'c':
                if (!strcmp(COMMAND_CRT, optarg))
                {
                    isCrt = 1;
                }
                else if (!strcmp(COMMAND_CRL, optarg))
                {
                    isCrt = 0;
                }
                else
                {
                    printf("Wrong command(-c)!\n");
                    Usage();
                    exit(0);
                }
                break;
            case 'f':
                testedFileName = optarg;
                break;
            case 's':
                caCrtFileName = optarg;
                break;
            default:
                Usage();
                exit(0);
        }
    }

    if (testedFileName == NULL || caCrtFileName == NULL)
    {
        printf("Wrong file name\n");
        Usage();
        exit(0);
    }

    // main
    ByteArray testedCrtCrl = BYTE_ARRAY_INITIALIZER; // Could contain either Certificate or CRL
    ByteArray caCrt = BYTE_ARRAY_INITIALIZER;

    // Copy DER files, specified in command line to ByteArray structure
    FileToByteArray(testedFileName, &testedCrtCrl);
    FileToByteArray(caCrtFileName, &caCrt);

    // Decoding CA certificate
    CertificateX509 caCrtStuct = CERTIFICATE_X509_INITIALIZER;
    PKIError errorCode = DecodeCertificate(caCrt, &caCrtStuct);

    if (errorCode != PKI_SUCCESS)
    {
        printf("Unable to decode CA Certificate!\n");
        printf("Error code: %d\n", errorCode);
    }

    ByteArray caPublicKey = BYTE_ARRAY_INITIALIZER;
    // Verifies Certificate or CRL depending on request
    if (isCrt)
    {
        errorCode = CheckCertificate(testedCrtCrl, caCrtStuct.pubKey);
    }
    else
    {
        caPublicKey.data = caCrtStuct.pubKey.data;
        caPublicKey.len = caCrtStuct.pubKey.len;
        ParsePublicKey(&caPublicKey);
        CertificateList crlStruct = CRL_INITIALIZER;
        errorCode = DecodeCertificateList(testedCrtCrl, &crlStruct, caPublicKey);
    }

    if (errorCode == PKI_SUCCESS)
    {
        printf("Verification SUCCESS!\n");
    }
    else
    {
        printf("Verification FAILED!\n");
        printf("Error code: %d\n", errorCode);
    }

    // Free the allocated memory
    OICFree(testedCrtCrl.data);
    OICFree(caCrt.data);

    return 0;
}