// File: /workspace/github_c_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rcx, 0x68(%rsp)
movq %rdx, %r12
movq %rsi, %r14
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x2180
movq %rbx, %rdi
movq %r14, %rsi
movl %eax, %edx
callq 0x860b
testq %rax, %rax
je 0x7d22
leaq -0x28e5(%rip), %rdx     # 0x5293
movq %rbx, %rdi
movq %rax, 0x8(%rsp)
movl $0xa, %esi
callq 0x64dc
movq 0x8(%rsp), %rsi
movq %rax, %r14
testq %rax, %rax
je 0x7d51
cmpb $0x0, (%rsi)
je 0x7d51
movq %rsi, %r15
movzbl (%r15), %eax
cmpl $0x20, %eax
je 0x7bb5
cmpl $0x2c, %eax
jne 0x7bba
incq %r15
jmp 0x7ba7
leaq 0x1(%r15), %r13
xorl %ebp, %ebp
movzbl (%r15,%rbp), %eax
testl %eax, %eax
je 0x7d51
cmpl $0x3d, %eax
je 0x7bda
incq %rbp
incq %r13
jmp 0x7bc0
leal 0x1(%rbp), %esi
movq %rbx, %rdi
callq 0x5281
movq 0x8(%rsp), %rsi
testq %rax, %rax
je 0x7d51
movq %rbx, 0x18(%rsp)
movq %r12, 0x10(%rsp)
movl %ebp, %r12d
movq %rax, %rdi
movq %r15, %rsi
movq %r12, %rdx
movq %rax, %rbx
callq 0x2050
movq %rbx, 0x60(%rsp)
movb $0x0, (%rbx,%r12)
leaq (%r15,%rbp), %rcx
incq %rcx
movzbl (%rcx), %eax
cmpl $0x22, %eax
je 0x7c2f
cmpl $0x27, %eax
jne 0x7c9a
movq %rcx, 0x58(%rsp)
addq %r15, %rbp
addq $0x2, %rbp
movq $-0x1, %r15
movb 0x1(%r13), %cl
incq %r13
incq %r15
cmpb %al, %cl
je 0x7c54
testb %cl, %cl
jne 0x7c42
leal 0x1(%r15), %esi
movq 0x18(%rsp), %rbx
movq %rbx, %rdi
callq 0x5281
movq %rax, %r12
testq %rax, %rax
je 0x7c83
movl %r15d, %r15d
movq %r12, %rdi
movq %rbp, %rsi
movq %r15, %rdx
callq 0x2050
movb $0x0, (%r12,%r15)
movb (%r13), %al
xorl %r15d, %r15d
movq 0x58(%rsp), %rcx
cmpb (%rcx), %al
sete %r15b
addq %r13, %r15
jmp 0x7ce9
xorl %r15d, %r15d
movq 0x18(%rsp), %rbx
movzbl (%r13,%r15), %eax
testl %eax, %eax
je 0x7cb6
cmpl $0x2c, %eax
je 0x7cb6
incq %r15
jmp 0x7ca2
movq %rcx, %rbp
leal 0x1(%r15), %esi
movq %rbx, %rdi
callq 0x5281
movq %rax, %r12
addq %r15, %r13
testq %rax, %rax
je 0x7ce6
movl %r15d, %r15d
movq %r12, %rdi
movq %rbp, %rsi
movq %r15, %rdx
callq 0x2050
movb $0x0, (%r12,%r15)
movq %r13, %r15
testq %r12, %r12
movq 0x60(%rsp), %rsi
je 0x7d3f
movq %r14, %rdi
movq %r12, %rdx
movq %rsi, %r12
callq 0x65fa
movq %rbx, %rdi
movq %r12, %rsi
callq 0x5293
cmpb $0x0, (%r15)
movq 0x10(%rsp), %r12
movq 0x8(%rsp), %rsi
jne 0x7ba7
jmp 0x7d51
leaq 0x609d(%rip), %rsi      # 0xddc6
leaq 0x612e(%rip), %rdx      # 0xde5e
xorl %r14d, %r14d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x539c
jmp 0x7d59
movq %rbx, %rdi
callq 0x5293
movq 0x10(%rsp), %r12
movq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x5293
testq %r14, %r14
je 0x839b
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6a51
movq %rax, %rbp
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6aa9
movq %rax, %r13
leaq 0x6066(%rip), %rsi      # 0xddeb
movq %r14, %rdi
callq 0x67a3
testq %rax, %rax
je 0x7d97
cmpb $0x0, (%rax)
jne 0x7dc2
movq %rbx, %rdi
movq %r13, %rsi
callq 0xc264
leaq 0x6042(%rip), %r15      # 0xddeb
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x65fa
movq %r14, %rdi
movq %r15, %rsi
callq 0x67a3
movq %rax, 0x10(%rsp)
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xc264
leaq 0x5738(%rip), %rsi      # 0xd511
movq %r14, %rdi
movq %rax, %rdx
callq 0x65fa
leaq 0x600d(%rip), %rsi      # 0xddf8
movq %rbx, %rdi
callq 0xc264
leaq 0x5ff7(%rip), %rsi      # 0xddf1
movq %r14, %rdi
movq %rax, %rdx
callq 0x65fa
leaq 0x5ffc(%rip), %rsi      # 0xde08
movq %rbx, %rdi
callq 0xc264
leaq 0x5fea(%rip), %rsi      # 0xde05
movq %r14, %rdi
movq %rax, %rdx
callq 0x65fa
leaq 0x56df(%rip), %rsi      # 0xd50c
movq %rbx, %rdi
callq 0xc264
leaq 0x5fd5(%rip), %rsi      # 0xde11
movq %r14, %rdi
movq %rax, %rdx
callq 0x65fa
movq %r13, %rdi
callq 0x2180
leaq 0x6(%rax), %rsi
movq %rbx, %rdi
callq 0x5281
movq %rax, %r15
movl $0x70706d78, (%rax)     # imm = 0x70706D78
movb $0x2f, 0x4(%rax)
leaq 0x5(%rax), %r12
movq %r13, %rdi
callq 0x2180
movq %r12, %rdi
movq %r13, %rsi
movq %rax, %rdx
callq 0x2050
movq %r13, 0x18(%rsp)
movq %r13, %rdi
callq 0x2180
movb $0x0, 0x5(%r15,%rax)
leaq 0x5f7f(%rip), %rsi      # 0xde1b
movq %r14, %rdi
movq %r15, %rdx
callq 0x65fa
leaq 0x90(%rsp), %r13
movq %r13, %rdi
callq 0x6b98
movq %rbp, %rdi
callq 0x2180
movq %r13, %rdi
movq %rbp, 0x8(%rsp)
movq %rbp, %rsi
movl %eax, %edx
callq 0x6bbe
leaq 0x5297(%rip), %r15      # 0xd16f
movq %r13, %rdi
movq %r15, %rsi
movl $0x1, %edx
callq 0x6bbe
movq 0x10(%rsp), %r12
movq %r12, %rdi
callq 0x2180
movq %r13, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6bbe
movq %r13, %rdi
movq %r15, %rsi
movl $0x1, %edx
callq 0x6bbe
movq 0x68(%rsp), %r12
movq %r12, %rdi
callq 0x2180
movq %r13, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6bbe
leaq 0x40(%rsp), %rbp
movq %rbp, %rdi
movq %r13, %rsi
callq 0x74f0
movq %r13, %rdi
callq 0x6b98
movq %r13, %rdi
movq %rbp, %rsi
movl $0x10, %edx
callq 0x6bbe
movq %r13, %rdi
movq %r15, %rsi
movl $0x1, %edx
callq 0x6bbe
leaq 0x5e87(%rip), %rsi      # 0xddf2
movq %r14, %rdi
callq 0x67a3
movq %rax, %r12
movq %rax, %rdi
callq 0x2180
movq %r13, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6bbe
movq %r13, %rdi
movq %r15, %rsi
movl $0x1, %edx
callq 0x6bbe
movq %r14, %rdi
leaq 0x5e4c(%rip), %rsi      # 0xddf1
callq 0x67a3
movq %rax, %r15
movq %rax, %rdi
callq 0x2180
movq %r13, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x6bbe
movq %rbp, %rdi
movq %r13, %rsi
callq 0x74f0
movaps (%rbp), %xmm0
movaps %xmm0, 0x80(%rsp)
movq %r13, %rdi
callq 0x6b98
leaq 0x5e3e(%rip), %rsi      # 0xde26
movq %r13, %rdi
movl $0xd, %edx
callq 0x6bbe
movq %r14, %rdi
leaq 0x5e1c(%rip), %rsi      # 0xde1b
callq 0x67a3
movq %rax, %r15
movq %rax, %rdi
callq 0x2180
movq %r13, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x6bbe
movq %r14, %rdi
leaq 0x5deb(%rip), %rsi      # 0xde11
callq 0x67a3
movq %rax, %rdi
leaq 0x54d7(%rip), %rsi      # 0xd50c
callq 0x22e0
testl %eax, %eax
je 0x8057
leaq 0x5def(%rip), %rsi      # 0xde34
leaq 0x90(%rsp), %rdi
movl $0x21, %edx
callq 0x6bbe
leaq 0x40(%rsp), %r15
leaq 0x90(%rsp), %r12
movq %r15, %rdi
movq %r12, %rsi
callq 0x74f0
movaps (%r15), %xmm0
movaps %xmm0, 0x70(%rsp)
movq %r12, %rdi
callq 0x6b98
xorl %eax, %eax
leaq 0x5f77(%rip), %rbp      # 0xe000
movzbl 0x80(%rsp,%rax), %ecx
movl %ecx, %edx
shrl $0x4, %edx
movb (%rdx,%rbp), %dl
movb %dl, 0x20(%rsp,%rax,2)
andl $0xf, %ecx
movb (%rcx,%rbp), %cl
movb %cl, 0x21(%rsp,%rax,2)
incq %rax
cmpq $0x10, %rax
jne 0x8089
leaq 0x90(%rsp), %r15
leaq 0x20(%rsp), %rsi
movq %r15, %rdi
movl $0x20, %edx
callq 0x6bbe
leaq 0x509e(%rip), %r13      # 0xd16f
movq %r15, %rdi
movq %r13, %rsi
movl $0x1, %edx
callq 0x6bbe
leaq 0x5d0a(%rip), %rsi      # 0xddf2
movq %r14, %rdi
callq 0x67a3
movq %rax, %r12
movq %rax, %rdi
callq 0x2180
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6bbe
movq %r15, %rdi
movq %r13, %rsi
movl $0x1, %edx
callq 0x6bbe
leaq 0x5ce6(%rip), %rsi      # 0xde05
movq %r14, %rdi
callq 0x67a3
movq %rax, %r12
movq %rax, %rdi
callq 0x2180
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6bbe
movq %r15, %rdi
movq %r13, %rsi
movl $0x1, %edx
callq 0x6bbe
leaq 0x5c9b(%rip), %rsi      # 0xddf1
movq %r14, %rdi
callq 0x67a3
movq %rax, %r12
movq %rax, %rdi
callq 0x2180
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6bbe
movq %r15, %rdi
movq %r13, %rsi
movl $0x1, %edx
callq 0x6bbe
leaq 0x5c84(%rip), %rsi      # 0xde11
movq %r14, %rdi
callq 0x67a3
movq %rax, %r12
movq %rax, %rdi
callq 0x2180
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6bbe
movq %r15, %rdi
movq %r13, %rsi
movl $0x1, %edx
callq 0x6bbe
xorl %eax, %eax
movzbl 0x70(%rsp,%rax), %ecx
movl %ecx, %edx
shrl $0x4, %edx
movb (%rdx,%rbp), %dl
movb %dl, 0x20(%rsp,%rax,2)
andl $0xf, %ecx
movb (%rcx,%rbp), %cl
movb %cl, 0x21(%rsp,%rax,2)
incq %rax
cmpq $0x10, %rax
jne 0x81bf
leaq 0x90(%rsp), %r15
leaq 0x20(%rsp), %rsi
movq %r15, %rdi
movl $0x20, %edx
callq 0x6bbe
leaq 0x40(%rsp), %rdi
movq %r15, %rsi
callq 0x74f0
movl $0x21, %esi
movq %rbx, %rdi
callq 0x5281
xorl %ecx, %ecx
movq 0x8(%rsp), %r12
movq 0x18(%rsp), %r13
movzbl 0x40(%rsp,%rcx), %edx
movl %edx, %esi
shrl $0x4, %esi
movb (%rsi,%rbp), %sil
movb %sil, 0x20(%rsp,%rcx,2)
andl $0xf, %edx
movb (%rdx,%rbp), %dl
movb %dl, 0x21(%rsp,%rcx,2)
incq %rcx
cmpq $0x10, %rcx
jne 0x8223
movaps 0x20(%rsp), %xmm0
movaps 0x30(%rsp), %xmm1
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
movb $0x0, 0x20(%rax)
leaq 0x55b5(%rip), %r15      # 0xd81a
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x65fa
leaq 0x5297(%rip), %rdx      # 0xd511
movq %rbx, %rdi
movq %r14, %rsi
xorl %ecx, %ecx
movl $0x1, %r8d
callq 0x83cb
leaq 0x5b57(%rip), %rdx      # 0xddeb
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
movl $0x1, %r8d
callq 0x83cb
leaq 0x5b43(%rip), %rdx      # 0xddf2
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
movl $0x1, %r8d
callq 0x83cb
leaq 0x5b27(%rip), %rdx      # 0xddf1
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
movl $0x1, %r8d
callq 0x83cb
leaq 0x5b20(%rip), %rdx      # 0xde05
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x83cb
leaq 0x5b14(%rip), %rdx      # 0xde11
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x83cb
leaq 0x5b06(%rip), %rdx      # 0xde1b
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
movl $0x1, %r8d
callq 0x83cb
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x83cb
leaq 0x5b12(%rip), %rdx      # 0xde56
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x83cb
movq %rax, %r15
movq %rbx, %rdi
movq %r12, %rsi
callq 0x5293
movq %rbx, %rdi
movq %r13, %rsi
callq 0x5293
movq %r14, %rdi
callq 0x655f
movq %r15, %rdi
callq 0x2180
movq %rbx, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x79e4
movq %rax, %r14
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5293
jmp 0x83b6
leaq 0x5a24(%rip), %rsi      # 0xddc6
leaq 0x5a22(%rip), %rdx      # 0xddcb
xorl %r14d, %r14d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x539c
movq %r14, %rax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq