// File: /workspace/github_c_makefile_star2_O0/liuhaotian[P]xmppsh/libstrophe/src/sasl.c
// Function: sasl_digest_md5
char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
			const char *jid, const char *password) {
    hash_t *table;
    char *result = NULL;
    char *node, *domain, *realm;
    char *value;
    char *response;
    int rlen;
    struct MD5Context MD5;
    unsigned char digest[16], HA1[16], HA2[16];
    char hex[32];

    /* our digest response is 
	Hex( KD( HEX(MD5(A1)),
	  nonce ':' nc ':' cnonce ':' qop ':' HEX(MD5(A2))
	))

       where KD(k, s) = MD5(k ':' s),
	A1 = MD5( node ':' realm ':' password ) ':' nonce ':' cnonce
	A2 = "AUTHENTICATE" ':' "xmpp/" domain

       If there is an authzid it is ':'-appended to A1 */

    /* parse the challenge */
    table = _parse_digest_challenge(ctx, challenge);
    if (table == NULL) {
	xmpp_error(ctx, "SASL", "couldn't parse digest challenge");
	return NULL;
    }

    node = xmpp_jid_node(ctx, jid);
    domain = xmpp_jid_domain(ctx, jid);

    /* generate default realm of domain if one didn't come from the
       server */
    realm = hash_get(table, "realm");
    if (realm == NULL || strlen(realm) == 0) {
	hash_add(table, "realm", xmpp_strdup(ctx, domain));
	realm = hash_get(table, "realm");
    }

    /* add our response fields */
    hash_add(table, "username", xmpp_strdup(ctx, node));
    /* TODO: generate a random cnonce */
    hash_add(table, "cnonce", xmpp_strdup(ctx, "00DEADBEEF00"));
    hash_add(table, "nc", xmpp_strdup(ctx, "00000001"));
    hash_add(table, "qop", xmpp_strdup(ctx, "auth"));
    value = xmpp_alloc(ctx, 5 + strlen(domain) + 1);
    memcpy(value, "xmpp/", 5);
    memcpy(value+5, domain, strlen(domain));
    value[5+strlen(domain)] = '\0';
    hash_add(table, "digest-uri", value);
    
    /* generate response */

    /* construct MD5(node : realm : password) */
    MD5Init(&MD5);
    MD5Update(&MD5, (unsigned char *)node, strlen(node));
    MD5Update(&MD5, (unsigned char *)":", 1);
    MD5Update(&MD5, (unsigned char *)realm, strlen(realm));
    MD5Update(&MD5, (unsigned char *)":", 1);
    MD5Update(&MD5, (unsigned char *)password, strlen(password));
    MD5Final(digest, &MD5);

    /* digest now contains the first field of A1 */

    MD5Init(&MD5);
    MD5Update(&MD5, digest, 16);
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "nonce");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "cnonce");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Final(digest, &MD5);

    /* now digest is MD5(A1) */
    memcpy(HA1, digest, 16);

    /* construct MD5(A2) */
    MD5Init(&MD5);
    MD5Update(&MD5, (unsigned char *)"AUTHENTICATE:", 13);
    value = hash_get(table, "digest-uri");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    if (strcmp(hash_get(table, "qop"), "auth") != 0) {
	MD5Update(&MD5, (unsigned char *)":00000000000000000000000000000000",
		  33);
    }
    MD5Final(digest, &MD5);

    memcpy(HA2, digest, 16);

    /* construct response */
    MD5Init(&MD5);
    _digest_to_hex((char *)HA1, hex);
    MD5Update(&MD5, (unsigned char *)hex, 32);
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "nonce");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "nc");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "cnonce");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "qop");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Update(&MD5, (unsigned char *)":", 1);
    _digest_to_hex((char *)HA2, hex);
    MD5Update(&MD5, (unsigned char *)hex, 32);
    MD5Final(digest, &MD5);

    response = xmpp_alloc(ctx, 32+1);
    _digest_to_hex((char *)digest, hex);
    memcpy(response, hex, 32);
    response[32] = '\0';
    hash_add(table, "response", response);

    /* construct reply */
    result = NULL;
    rlen = 0;
    result = _add_key(ctx, table, "username", result, &rlen, 1); 
    result = _add_key(ctx, table, "realm", result, &rlen, 1); 
    result = _add_key(ctx, table, "nonce", result, &rlen, 1); 
    result = _add_key(ctx, table, "cnonce", result, &rlen, 1); 
    result = _add_key(ctx, table, "nc", result, &rlen, 0); 
    result = _add_key(ctx, table, "qop", result, &rlen, 0); 
    result = _add_key(ctx, table, "digest-uri", result, &rlen, 1); 
    result = _add_key(ctx, table, "response", result, &rlen, 0); 
    result = _add_key(ctx, table, "charset", result, &rlen, 0);
 
    xmpp_free(ctx, node);
    xmpp_free(ctx, domain);
    hash_release(table); /* also frees value strings */

    /* reuse response for the base64 encode of our result */
    response = base64_encode(ctx, (unsigned char *)result, strlen(result));
    xmpp_free(ctx, result);

    return response;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1c0, %rsp            # imm = 0x1C0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xb700
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0xae31
movq -0x10(%rbp), %rdi
leaq 0x9f80(%rip), %rsi      # 0x14d96
leaq 0x9f7e(%rip), %rdx      # 0x14d9b
movb $0x0, %al
callq 0x68a0
movq $0x0, -0x8(%rbp)
jmp 0xb6e4
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x8ed0
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x8f60
movq %rax, -0x48(%rbp)
movq -0x30(%rbp), %rdi
leaq 0x9f5d(%rip), %rsi      # 0x14dbb
callq 0x8a80
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0xae7d
movq -0x50(%rbp), %rdi
callq 0x2180
cmpq $0x0, %rax
jne 0xaebf
movq -0x30(%rbp), %rax
movq %rax, -0x118(%rbp)
movq -0x10(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x13560
movq -0x118(%rbp), %rdi
movq %rax, %rdx
leaq 0x9f15(%rip), %rsi      # 0x14dbb
callq 0x87e0
movq -0x30(%rbp), %rdi
leaq 0x9f05(%rip), %rsi      # 0x14dbb
callq 0x8a80
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x188(%rbp)
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x13560
movq -0x188(%rbp), %rdi
movq %rax, %rdx
leaq 0x962a(%rip), %rsi      # 0x14512
callq 0x87e0
movq -0x30(%rbp), %rax
movq %rax, -0x180(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x9ec5(%rip), %rsi      # 0x14dc8
callq 0x13560
movq -0x180(%rbp), %rdi
movq %rax, %rdx
leaq 0x9ea8(%rip), %rsi      # 0x14dc1
callq 0x87e0
movq -0x30(%rbp), %rax
movq %rax, -0x178(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x9ea4(%rip), %rsi      # 0x14dd8
callq 0x13560
movq -0x178(%rbp), %rdi
movq %rax, %rdx
leaq 0x9e8b(%rip), %rsi      # 0x14dd5
callq 0x87e0
movq -0x30(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x95a8(%rip), %rsi      # 0x1450d
callq 0x13560
movq -0x170(%rbp), %rdi
movq %rax, %rdx
leaq 0x9e66(%rip), %rsi      # 0x14de1
callq 0x87e0
movq -0x10(%rbp), %rax
movq %rax, -0x168(%rbp)
movq -0x48(%rbp), %rdi
callq 0x2180
movq -0x168(%rbp), %rdi
movq %rax, %rsi
addq $0x5, %rsi
addq $0x1, %rsi
callq 0x6680
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movl 0x9e2c(%rip), %ecx      # 0x14de5
movl %ecx, (%rax)
movb 0x9e28(%rip), %cl       # 0x14de9
movb %cl, 0x4(%rax)
movq -0x58(%rbp), %rax
addq $0x5, %rax
movq %rax, -0x160(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x158(%rbp)
movq -0x48(%rbp), %rdi
callq 0x2180
movq -0x160(%rbp), %rdi
movq -0x158(%rbp), %rsi
movq %rax, %rdx
callq 0x2050
movq -0x58(%rbp), %rax
movq %rax, -0x150(%rbp)
movq -0x48(%rbp), %rdi
callq 0x2180
movq %rax, %rcx
movq -0x150(%rbp), %rax
addq $0x5, %rcx
movb $0x0, (%rax,%rcx)
movq -0x30(%rbp), %rdi
movq -0x58(%rbp), %rdx
leaq 0x9db9(%rip), %rsi      # 0x14deb
callq 0x87e0
leaq -0xbc(%rbp), %rdi
callq 0x90d0
movq -0x40(%rbp), %rax
movq %rax, -0x148(%rbp)
movq -0x40(%rbp), %rdi
callq 0x2180
movq -0x148(%rbp), %rsi
movl %eax, %edx
leaq -0xbc(%rbp), %rdi
callq 0x9140
leaq -0xbc(%rbp), %rdi
leaq 0x91ea(%rip), %rsi      # 0x14264
movl $0x1, %edx
callq 0x9140
movq -0x50(%rbp), %rax
movq %rax, -0x140(%rbp)
movq -0x50(%rbp), %rdi
callq 0x2180
movq -0x140(%rbp), %rsi
movl %eax, %edx
leaq -0xbc(%rbp), %rdi
callq 0x9140
leaq -0xbc(%rbp), %rdi
leaq 0x91a9(%rip), %rsi      # 0x14264
movl $0x1, %edx
callq 0x9140
movq -0x28(%rbp), %rax
movq %rax, -0x138(%rbp)
movq -0x28(%rbp), %rdi
callq 0x2180
movq -0x138(%rbp), %rsi
movl %eax, %edx
leaq -0xbc(%rbp), %rdi
callq 0x9140
leaq -0xd0(%rbp), %rdi
leaq -0xbc(%rbp), %rsi
callq 0xa100
leaq -0xbc(%rbp), %rdi
callq 0x90d0
leaq -0xd0(%rbp), %rsi
leaq -0xbc(%rbp), %rdi
movl $0x10, %edx
callq 0x9140
leaq -0xbc(%rbp), %rdi
leaq 0x9131(%rip), %rsi      # 0x14264
movl $0x1, %edx
callq 0x9140
movq -0x30(%rbp), %rdi
leaq 0x9c7a(%rip), %rsi      # 0x14dc2
callq 0x8a80
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x130(%rbp)
movq -0x58(%rbp), %rdi
callq 0x2180
movq -0x130(%rbp), %rsi
movl %eax, %edx
leaq -0xbc(%rbp), %rdi
callq 0x9140
leaq -0xbc(%rbp), %rdi
leaq 0x90dc(%rip), %rsi      # 0x14264
movl $0x1, %edx
callq 0x9140
movq -0x30(%rbp), %rdi
leaq 0x9c24(%rip), %rsi      # 0x14dc1
callq 0x8a80
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x128(%rbp)
movq -0x58(%rbp), %rdi
callq 0x2180
movq -0x128(%rbp), %rsi
movl %eax, %edx
leaq -0xbc(%rbp), %rdi
callq 0x9140
leaq -0xd0(%rbp), %rdi
leaq -0xbc(%rbp), %rsi
callq 0xa100
movq -0xd0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, -0xd8(%rbp)
leaq -0xbc(%rbp), %rdi
callq 0x90d0
leaq -0xbc(%rbp), %rdi
leaq 0x9bde(%rip), %rsi      # 0x14df6
movl $0xd, %edx
callq 0x9140
movq -0x30(%rbp), %rdi
leaq 0x9bbe(%rip), %rsi      # 0x14deb
callq 0x8a80
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x120(%rbp)
movq -0x58(%rbp), %rdi
callq 0x2180
movq -0x120(%rbp), %rsi
movl %eax, %edx
leaq -0xbc(%rbp), %rdi
callq 0x9140
movq -0x30(%rbp), %rdi
leaq 0x9b77(%rip), %rsi      # 0x14de1
callq 0x8a80
movq %rax, %rdi
leaq 0x9294(%rip), %rsi      # 0x1450d
callq 0x22e0
cmpl $0x0, %eax
je 0xb29b
leaq -0xbc(%rbp), %rdi
leaq 0x9b73(%rip), %rsi      # 0x14e04
movl $0x21, %edx
callq 0x9140
leaq -0xd0(%rbp), %rdi
leaq -0xbc(%rbp), %rsi
callq 0xa100
movq -0xd0(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, -0xe8(%rbp)
leaq -0xbc(%rbp), %rdi
callq 0x90d0
leaq -0xe0(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0xb9e0
leaq -0x110(%rbp), %rsi
leaq -0xbc(%rbp), %rdi
movl $0x20, %edx
callq 0x9140
leaq -0xbc(%rbp), %rdi
leaq 0x8f55(%rip), %rsi      # 0x14264
movl $0x1, %edx
callq 0x9140
movq -0x30(%rbp), %rdi
leaq 0x9a9e(%rip), %rsi      # 0x14dc2
callq 0x8a80
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movq -0x58(%rbp), %rdi
callq 0x2180
movq -0x1b8(%rbp), %rsi
movl %eax, %edx
leaq -0xbc(%rbp), %rdi
callq 0x9140
leaq -0xbc(%rbp), %rdi
leaq 0x8f00(%rip), %rsi      # 0x14264
movl $0x1, %edx
callq 0x9140
movq -0x30(%rbp), %rdi
leaq 0x9a5c(%rip), %rsi      # 0x14dd5
callq 0x8a80
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x1b0(%rbp)
movq -0x58(%rbp), %rdi
callq 0x2180
movq -0x1b0(%rbp), %rsi
movl %eax, %edx
leaq -0xbc(%rbp), %rdi
callq 0x9140
leaq -0xbc(%rbp), %rdi
leaq 0x8eab(%rip), %rsi      # 0x14264
movl $0x1, %edx
callq 0x9140
movq -0x30(%rbp), %rdi
leaq 0x99f3(%rip), %rsi      # 0x14dc1
callq 0x8a80
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x1a8(%rbp)
movq -0x58(%rbp), %rdi
callq 0x2180
movq -0x1a8(%rbp), %rsi
movl %eax, %edx
leaq -0xbc(%rbp), %rdi
callq 0x9140
leaq -0xbc(%rbp), %rdi
leaq 0x8e56(%rip), %rsi      # 0x14264
movl $0x1, %edx
callq 0x9140
movq -0x30(%rbp), %rdi
leaq 0x99be(%rip), %rsi      # 0x14de1
callq 0x8a80
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x1a0(%rbp)
movq -0x58(%rbp), %rdi
callq 0x2180
movq -0x1a0(%rbp), %rsi
movl %eax, %edx
leaq -0xbc(%rbp), %rdi
callq 0x9140
leaq -0xbc(%rbp), %rdi
leaq 0x8e01(%rip), %rsi      # 0x14264
movl $0x1, %edx
callq 0x9140
leaq -0xf0(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0xb9e0
leaq -0x110(%rbp), %rsi
leaq -0xbc(%rbp), %rdi
movl $0x20, %edx
callq 0x9140
leaq -0xd0(%rbp), %rdi
leaq -0xbc(%rbp), %rsi
callq 0xa100
movq -0x10(%rbp), %rdi
movl $0x21, %esi
callq 0x6680
movq %rax, -0x60(%rbp)
leaq -0xd0(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0xb9e0
movq -0x60(%rbp), %rax
movq -0x110(%rbp), %rcx
movq %rcx, (%rax)
movq -0x108(%rbp), %rcx
movq %rcx, 0x8(%rax)
movq -0x100(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0xf8(%rbp), %rcx
movq %rcx, 0x18(%rax)
movq -0x60(%rbp), %rax
movb $0x0, 0x20(%rax)
movq -0x30(%rbp), %rdi
movq -0x60(%rbp), %rdx
leaq 0x9305(%rip), %rsi      # 0x1481b
callq 0x87e0
movq $0x0, -0x38(%rbp)
movl $0x0, -0x64(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rcx
leaq 0x8fd5(%rip), %rdx      # 0x14512
leaq -0x64(%rbp), %r8
movl $0x1, %r9d
callq 0xba80
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rcx
leaq 0x9858(%rip), %rdx      # 0x14dbb
leaq -0x64(%rbp), %r8
movl $0x1, %r9d
callq 0xba80
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rcx
leaq 0x9839(%rip), %rdx      # 0x14dc2
leaq -0x64(%rbp), %r8
movl $0x1, %r9d
callq 0xba80
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rcx
leaq 0x9812(%rip), %rdx      # 0x14dc1
leaq -0x64(%rbp), %r8
movl $0x1, %r9d
callq 0xba80
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rcx
leaq 0x9800(%rip), %rdx      # 0x14dd5
leaq -0x64(%rbp), %r8
xorl %r9d, %r9d
callq 0xba80
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rcx
leaq 0x97e9(%rip), %rdx      # 0x14de1
leaq -0x64(%rbp), %r8
xorl %r9d, %r9d
callq 0xba80
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rcx
leaq 0x97d0(%rip), %rdx      # 0x14deb
leaq -0x64(%rbp), %r8
movl $0x1, %r9d
callq 0xba80
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rcx
leaq 0x91da(%rip), %rdx      # 0x1481b
leaq -0x64(%rbp), %r8
xorl %r9d, %r9d
callq 0xba80
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rcx
leaq 0x97c2(%rip), %rdx      # 0x14e26
leaq -0x64(%rbp), %r8
xorl %r9d, %r9d
callq 0xba80
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x66c0
movq -0x10(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x66c0
movq -0x30(%rbp), %rdi
callq 0x86f0
movq -0x10(%rbp), %rax
movq %rax, -0x198(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x190(%rbp)
movq -0x38(%rbp), %rdi
callq 0x2180
movq -0x198(%rbp), %rdi
movq -0x190(%rbp), %rsi
movl %eax, %edx
callq 0xaaa0
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x66c0
movq -0x60(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x1c0, %rsp            # imm = 0x1C0
popq %rbp
retq
nopw %cs:(%rax,%rax)