Пример #1
0
static DWORD VerifyWeakSignature(
    TMPQArchive * ha,
    PMPQ_SIGNATURE_INFO pSI)
{
    BYTE RevSignature[MPQ_WEAK_SIGNATURE_SIZE];
    BYTE Md5Digest[MD5_DIGEST_SIZE];
    rsa_key key;
    int hash_idx = find_hash("md5");
    int result = 0;

    // Calculate hash of the entire archive, skipping the (signature) file
    if(!CalculateMpqHashMd5(ha, pSI, Md5Digest))
        return ERROR_VERIFY_FAILED;

    // Import the Blizzard key in OpenSSL format
    if(!decode_base64_key(szBlizzardWeakPublicKey, &key))
        return ERROR_VERIFY_FAILED;

    // Verify the signature
    memcpy(RevSignature, &pSI->Signature[8], MPQ_WEAK_SIGNATURE_SIZE);
    memrev(RevSignature, MPQ_WEAK_SIGNATURE_SIZE);
    rsa_verify_hash_ex(RevSignature, MPQ_WEAK_SIGNATURE_SIZE, Md5Digest, sizeof(Md5Digest), LTC_LTC_PKCS_1_V1_5, hash_idx, 0, &result, &key);
    rsa_free(&key);

    // Return the result
    return result ? ERROR_WEAK_SIGNATURE_OK : ERROR_WEAK_SIGNATURE_ERROR;
}
Пример #2
0
int SSignFileFinish(TMPQArchive * ha)
{
    MPQ_SIGNATURE_INFO si;
    unsigned long signature_len = MPQ_WEAK_SIGNATURE_SIZE;
    BYTE WeakSignature[MPQ_SIGNATURE_FILE_SIZE];
    BYTE Md5Digest[MD5_DIGEST_SIZE];
    rsa_key key;
    int hash_idx = find_hash("md5");

    // Sanity checks
    assert((ha->dwFlags & MPQ_FLAG_CHANGED) == 0);
    assert(ha->dwFileFlags3 == MPQ_FILE_EXISTS);

    // Query the weak signature info
    memset(&si, 0, sizeof(MPQ_SIGNATURE_INFO));
    if(!QueryMpqSignatureInfo(ha, &si))
        return ERROR_FILE_CORRUPT;

    // There must be exactly one signature
    if(si.SignatureTypes != SIGNATURE_TYPE_WEAK)
        return ERROR_FILE_CORRUPT;

    // Calculate MD5 of the entire archive
    if(!CalculateMpqHashMd5(ha, &si, Md5Digest))
        return ERROR_VERIFY_FAILED;

    // Decode the private key
    if(!decode_base64_key(szBlizzardWeakPrivateKey, &key))
        return ERROR_VERIFY_FAILED;

    // Sign the hash
    memset(WeakSignature, 0, sizeof(WeakSignature));
    rsa_sign_hash_ex(Md5Digest, sizeof(Md5Digest), WeakSignature + 8, &signature_len, LTC_LTC_PKCS_1_V1_5, 0, 0, hash_idx, 0, &key);
    memrev(WeakSignature + 8, MPQ_WEAK_SIGNATURE_SIZE); 
    rsa_free(&key);

    // Write the signature to the MPQ. Don't use SFile* functions, but write the hash directly
    if(!FileStream_Write(ha->pStream, &si.BeginExclude, WeakSignature, MPQ_SIGNATURE_FILE_SIZE))
        return GetLastError();

    return ERROR_SUCCESS;
}
Пример #3
0
static DWORD VerifyStrongSignatureWithKey(
    unsigned char * reversed_signature,
    unsigned char * padded_digest,
    const char * szPublicKey) {
    rsa_key key;
    int result = 0;

    // Import the Blizzard key in OpenSSL format
    if (!decode_base64_key(szPublicKey, &key)) {
        assert(false);
        return ERROR_VERIFY_FAILED;
    }

    // Verify the signature
#warning rsa_verify_simple is missing
//    if (rsa_verify_simple(reversed_signature, MPQ_STRONG_SIGNATURE_SIZE, padded_digest, MPQ_STRONG_SIGNATURE_SIZE, &result, &key) != CRYPT_OK)
//        return ERROR_VERIFY_FAILED;

    // Free the key and return result
    rsa_free(&key);
    return result ? ERROR_STRONG_SIGNATURE_OK : ERROR_STRONG_SIGNATURE_ERROR;
}
Пример #4
0
/*
 * Parse the dnskey from the string. The string contains the flags, 
 * protocol, algorithm and the base64 key delimited by spaces.
 */
int
val_parse_dnskey_string(char *keystr, size_t keystrlen,
                        val_dnskey_rdata_t ** dnskey_rdata)
{
    char           *sp = keystr;
    char           *ep = sp + keystrlen;
    char            token[NS_MAXDNAME];
    char           *keyptr = NULL;
    char           *cp;
    size_t         bufsize;
    size_t         buflen;
    u_char         *buf;
    u_char         *bp;
    u_int16_t       flags;

    if (keystr == NULL || dnskey_rdata == NULL)
        return VAL_BAD_ARGUMENT;

    (*dnskey_rdata) =
        (val_dnskey_rdata_t *) MALLOC(sizeof(val_dnskey_rdata_t));
    if ((*dnskey_rdata) == NULL)
        return VAL_OUT_OF_MEMORY;

    TOK_IN_STR();
    (*dnskey_rdata)->flags = (int)strtol(token, (char **)NULL, 10);

    TOK_IN_STR();
    (*dnskey_rdata)->protocol = (int)strtol(token, (char **)NULL, 10);

    TOK_IN_STR();
    (*dnskey_rdata)->algorithm = (int)strtol(token, (char **)NULL, 10);

    if (sp >= ep) {
        FREE(*dnskey_rdata);
        *dnskey_rdata = NULL;
        return VAL_CONF_PARSE_ERROR;
    }
    /*
     * What follows is the public key in base64.
     */

    /*
     * Remove any white spaces
     */
    for (cp = sp; sp < ep; sp++) {
        if (!isspace(*sp)) {
            if (keyptr == NULL)
                keyptr = cp;
            if (cp != sp)
                *cp = *sp;
            cp++;
        }
    }
    *cp = '\0';
    ep = cp; /* this is the last character in the public key */

    if (keyptr == NULL || keyptr >= ep) {
        FREE(*dnskey_rdata);
        *dnskey_rdata = NULL;
        return VAL_CONF_PARSE_ERROR;
    }
    bufsize = ep - keyptr;
    (*dnskey_rdata)->public_key =
        (u_char *) MALLOC(bufsize * sizeof(char));
    if ((*dnskey_rdata)->public_key == NULL) {
        FREE(*dnskey_rdata);
        *dnskey_rdata = NULL;
        return VAL_OUT_OF_MEMORY;
    }

    /*
     * decode the base64 public key 
     */
    if (((*dnskey_rdata)->public_key_len = 
                decode_base64_key(keyptr, (*dnskey_rdata)->
                                  public_key, bufsize)) <= 0) {

        FREE((*dnskey_rdata)->public_key);
        FREE(*dnskey_rdata);
        *dnskey_rdata = NULL;
        return VAL_BAD_ARGUMENT;
    }

    /*
     * For calculating the keytag, we need the 
     * complete DNSKEY RDATA in wire format
     */
    buflen = (*dnskey_rdata)->public_key_len + sizeof(u_int16_t) +      /* flags */
        sizeof(u_char) +      /* proto */
        sizeof(u_char);       /*algo */
    buf = (u_char *) MALLOC(buflen * sizeof(u_char));
    if (buf == NULL) {
        FREE((*dnskey_rdata)->public_key);
        FREE(*dnskey_rdata);
        *dnskey_rdata = NULL;
        return VAL_OUT_OF_MEMORY;
    }

    bp = buf;
    flags = (*dnskey_rdata)->flags;

    memcpy(bp, &flags, sizeof(u_int16_t));
    bp += sizeof(u_int16_t);
    *bp = (*dnskey_rdata)->protocol;
    bp++;
    *bp = (*dnskey_rdata)->algorithm;
    bp++;
    memcpy(bp, (*dnskey_rdata)->public_key,
           (*dnskey_rdata)->public_key_len);

    /*
     * Calculate the keytag 
     */
    if ((*dnskey_rdata)->algorithm == ALG_RSAMD5) {
        (*dnskey_rdata)->key_tag = rsamd5_keytag(buf, buflen);
    } else {
        (*dnskey_rdata)->key_tag = keytag(buf, buflen);
    }
    (*dnskey_rdata)->next = NULL;
    FREE(buf);

    return VAL_NO_ERROR;
}