// File: /workspace/github_c_makefile_star2_O2/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 $0xd8, %rsp
movq %rcx, %r15
movq %rdx, %r13
movq %rsi, %r14
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x2180
movq %rbx, %rdi
movq %r14, %rsi
movl %eax, %edx
callq 0x8242
testq %rax, %rax
je 0x79ba
movq %rax, %r12
leaq -0x26eb(%rip), %rdx     # 0x51a1
pushq $0xa
popq %rsi
movq %rbx, %rdi
callq 0x630c
testq %rax, %rax
je 0x79d7
movq %r13, 0x10(%rsp)
movq %r15, 0x28(%rsp)
movq %rax, 0x18(%rsp)
movq %r12, %r15
movb (%r15), %al
testb %al, %al
je 0x79f2
leaq 0x1(%r15), %r14
xorl %r13d, %r13d
movq %r15, %rsi
cmpb $0x20, %al
je 0x78d3
movzbl %al, %ecx
cmpl $0x2c, %ecx
jne 0x78e1
movb 0x1(%rsi), %al
incq %rsi
incq %r13
incq %r14
jmp 0x78c7
xorl %edx, %edx
testb %al, %al
je 0x79f2
movzbl %al, %eax
cmpl $0x3d, %eax
je 0x7902
movb 0x1(%r15,%r13), %al
incq %r13
incl %edx
incq %r14
jmp 0x78e3
movq %rbx, %rdi
callq 0x83fd
testq %rax, %rax
je 0x79f2
movq %rax, %rbp
leaq (%r15,%r13), %rsi
incq %rsi
movzbl (%rsi), %eax
cmpl $0x22, %eax
je 0x792a
cmpl $0x27, %eax
jne 0x796e
movq %rsi, 0x8(%rsp)
leaq (%r15,%r13), %rsi
addq $0x2, %rsi
pushq $-0x1
popq %rdx
movb 0x1(%r14), %cl
incq %r14
incl %edx
cmpb %al, %cl
je 0x794b
testb %cl, %cl
jne 0x793a
movq %rbx, %rdi
callq 0x83fd
movb (%r14), %cl
xorl %r15d, %r15d
movq 0x8(%rsp), %rdx
cmpb (%rdx), %cl
sete %r15b
addq %r14, %r15
movq 0x18(%rsp), %r14
jmp 0x7997
xorl %edx, %edx
movq %rsi, %r15
movq 0x18(%rsp), %r14
testb %al, %al
je 0x798f
movzbl %al, %eax
cmpl $0x2c, %eax
je 0x798f
movb 0x1(%r15), %al
incq %r15
incl %edx
jmp 0x7978
movq %rbx, %rdi
callq 0x83fd
testq %rax, %rax
je 0x79e7
movq %r14, %rdi
movq %rbp, %rsi
movq %rax, %rdx
callq 0x641a
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x51a1
jmp 0x78b2
leaq 0x5405(%rip), %rsi      # 0xcdc6
leaq 0x5496(%rip), %rdx      # 0xce5e
movq %rbx, %rdi
xorl %eax, %eax
callq 0x52aa
jmp 0x7fc2
movq %rbx, %rdi
movq %r12, %rsi
callq 0x51a1
jmp 0x7fc2
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x51a1
movq %rbx, %rdi
movq %r12, %rsi
callq 0x51a1
movq 0x18(%rsp), %r14
testq %r14, %r14
je 0x7fc2
movq %rbx, %rdi
movq 0x10(%rsp), %r15
movq %r15, %rsi
callq 0x67e8
movq %rax, %rbp
movq %rbx, %rdi
movq %r15, %rsi
callq 0x683e
movq %rax, %r13
leaq 0x53b8(%rip), %rsi      # 0xcdeb
movq %r14, %rdi
callq 0x657f
testq %rax, %rax
je 0x7a45
cmpb $0x0, (%rax)
jne 0x7a70
movq %rbx, %rdi
movq %r13, %rsi
callq 0xbcd4
leaq 0x5394(%rip), %r15      # 0xcdeb
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x641a
movq %r14, %rdi
movq %r15, %rsi
callq 0x657f
movq %rax, 0x20(%rsp)
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xbcd4
leaq 0x4a8a(%rip), %rsi      # 0xc511
movq %r14, %rdi
movq %rax, %rdx
callq 0x641a
leaq 0x535f(%rip), %rsi      # 0xcdf8
movq %rbx, %rdi
callq 0xbcd4
leaq 0x5349(%rip), %rsi      # 0xcdf1
movq %r14, %rdi
movq %rax, %rdx
callq 0x641a
leaq 0x534e(%rip), %rsi      # 0xce08
movq %rbx, %rdi
callq 0xbcd4
leaq 0x533c(%rip), %rsi      # 0xce05
movq %r14, %rdi
movq %rax, %rdx
callq 0x641a
leaq 0x4a31(%rip), %rsi      # 0xc50c
movq %rbx, %rdi
callq 0xbcd4
leaq 0x5327(%rip), %rsi      # 0xce11
movq %r14, %rdi
movq %rax, %rdx
callq 0x641a
movq %r13, %rdi
callq 0x2180
leaq 0x6(%rax), %rsi
movq %rbx, %rdi
callq 0x518f
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, 0x8(%rsp)
movq %r13, %rdi
callq 0x2180
movb $0x0, 0x5(%r15,%rax)
leaq 0x52d1(%rip), %rsi      # 0xce1b
movq %r14, %rdi
movq %r15, %rdx
callq 0x641a
leaq 0x80(%rsp), %r15
movq %r15, %rdi
callq 0x692c
movq %rbp, %rdi
callq 0x2180
movq %r15, %rdi
movq %rbp, 0x10(%rsp)
movq %rbp, %rsi
movl %eax, %edx
callq 0x694f
leaq 0x45e9(%rip), %rbp      # 0xc16f
pushq $0x1
popq %r13
movq %r15, %rdi
movq %rbp, %rsi
movl %r13d, %edx
callq 0x694f
movq 0x20(%rsp), %r12
movq %r12, %rdi
callq 0x2180
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x694f
movq %r15, %rdi
movq %rbp, %rsi
movl %r13d, %edx
callq 0x694f
movq 0x28(%rsp), %r12
movq %r12, %rdi
callq 0x2180
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x694f
leaq 0x30(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
callq 0x7248
movq %r15, %rdi
callq 0x692c
pushq $0x10
popq %rdx
movq %r15, %rdi
movq %r12, %rsi
callq 0x694f
movq %r15, %rdi
movq %rbp, %rsi
movl %r13d, %edx
callq 0x694f
leaq 0x51dd(%rip), %rsi      # 0xcdf2
movq %r14, %rdi
callq 0x657f
movq %rax, %r13
movq %rax, %rdi
callq 0x2180
movq %r15, %rdi
movq %r13, %rsi
movl %eax, %edx
callq 0x694f
movq %r15, %rdi
movq %rbp, %rsi
pushq $0x1
popq %rdx
callq 0x694f
movq %r14, %rdi
leaq 0x51a4(%rip), %rsi      # 0xcdf1
callq 0x657f
movq %rax, %r13
movq %rax, %rdi
callq 0x2180
movq %r15, %rdi
movq %r13, %rsi
movl %eax, %edx
callq 0x694f
movq %r12, %rdi
movq %r15, %rsi
callq 0x7248
movaps (%r12), %xmm0
movaps %xmm0, 0x50(%rsp)
movq %r15, %rdi
callq 0x692c
leaq 0x5198(%rip), %rsi      # 0xce26
pushq $0xd
popq %rdx
movq %r15, %rdi
callq 0x694f
movq %r14, %rdi
leaq 0x5178(%rip), %rsi      # 0xce1b
callq 0x657f
movq %rax, %r12
movq %rax, %rdi
callq 0x2180
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x694f
movq %r14, %rdi
leaq 0x5147(%rip), %rsi      # 0xce11
callq 0x657f
movq %rax, %rdi
leaq 0x4833(%rip), %rsi      # 0xc50c
callq 0x22e0
testl %eax, %eax
je 0x7cf9
leaq 0x514b(%rip), %rsi      # 0xce34
leaq 0x80(%rsp), %rdi
pushq $0x21
popq %rdx
callq 0x694f
leaq 0x30(%rsp), %r15
leaq 0x80(%rsp), %r12
movq %r15, %rdi
movq %r12, %rsi
callq 0x7248
movaps (%r15), %xmm0
leaq 0x40(%rsp), %rax
movaps %xmm0, (%rax)
movq %r12, %rdi
callq 0x692c
leaq 0x50(%rsp), %rdi
leaq 0x60(%rsp), %r15
movq %r15, %rsi
callq 0x7ff2
pushq $0x20
popq %rdx
movq %r12, %rdi
movq %r15, %rsi
callq 0x694f
leaq 0x4423(%rip), %r13      # 0xc16f
pushq $0x1
popq %rbp
movq %r12, %rdi
movq %r13, %rsi
movl %ebp, %edx
callq 0x694f
leaq 0x508f(%rip), %rsi      # 0xcdf2
movq %r14, %rdi
callq 0x657f
movq %rax, %r15
movq %rax, %rdi
callq 0x2180
movq %r12, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x694f
movq %r12, %rdi
movq %r13, %rsi
movl %ebp, %edx
callq 0x694f
leaq 0x506e(%rip), %rsi      # 0xce05
movq %r14, %rdi
callq 0x657f
movq %rax, %r15
movq %rax, %rdi
callq 0x2180
movq %r12, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x694f
movq %r12, %rdi
movq %r13, %rsi
movl %ebp, %edx
callq 0x694f
leaq 0x5026(%rip), %rsi      # 0xcdf1
movq %r14, %rdi
callq 0x657f
movq %rax, %r15
movq %rax, %rdi
callq 0x2180
movq %r12, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x694f
movq %r12, %rdi
movq %r13, %rsi
movl %ebp, %edx
callq 0x694f
leaq 0x5012(%rip), %rsi      # 0xce11
movq %r14, %rdi
callq 0x657f
movq %rax, %r15
movq %rax, %rdi
callq 0x2180
movq %r12, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x694f
movq %r12, %rdi
movq %r13, %rsi
movl %ebp, %edx
callq 0x694f
leaq 0x40(%rsp), %rdi
leaq 0x60(%rsp), %r13
movq %r13, %rsi
callq 0x7ff2
movq %r12, %rdi
movq %r13, %rsi
pushq $0x20
popq %rdx
callq 0x694f
leaq 0x30(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x7248
pushq $0x21
popq %rsi
movq %rbx, %rdi
callq 0x518f
movq %rax, %r12
movq %r15, %rdi
movq %r13, %rsi
callq 0x7ff2
movaps (%r13), %xmm0
movaps 0x10(%r13), %xmm1
movups %xmm1, 0x10(%r12)
movups %xmm0, (%r12)
movb $0x0, 0x20(%r12)
leaq 0x4983(%rip), %r15      # 0xc81a
movq %r14, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x641a
leaq 0x4665(%rip), %rdx      # 0xc511
movq %rbx, %rdi
movq %r14, %rsi
xorl %ecx, %ecx
movl %ebp, %r8d
callq 0x8022
leaq 0x4f28(%rip), %rdx      # 0xcdeb
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
movl %ebp, %r8d
callq 0x8022
movq %rbx, %rdi
movq %r14, %rsi
leaq 0x4f11(%rip), %rdx      # 0xcdf2
movq %rax, %rcx
movl %ebp, %r8d
callq 0x8022
movq %rbx, %rdi
movq %r14, %rsi
leaq 0x4ef8(%rip), %rdx      # 0xcdf1
movq %rax, %rcx
movl %ebp, %r8d
callq 0x8022
movq %rbx, %rdi
movq %r14, %rsi
leaq 0x4ef4(%rip), %rdx      # 0xce05
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x8022
movq %rbx, %rdi
movq %r14, %rsi
leaq 0x4ee8(%rip), %rdx      # 0xce11
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x8022
leaq 0x4ee0(%rip), %rdx      # 0xce1b
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
movl %ebp, %r8d
callq 0x8022
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x8022
leaq 0x4eef(%rip), %rdx      # 0xce56
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x8022
movq %rax, %r15
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
callq 0x51a1
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
callq 0x51a1
movq %r14, %rdi
callq 0x638a
movq %r15, %rdi
callq 0x2180
movq %rbx, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x771c
movq %rax, %r14
movq %rbx, %rdi
movq %r15, %rsi
callq 0x51a1
jmp 0x7fdd
leaq 0x4dfd(%rip), %rsi      # 0xcdc6
leaq 0x4dfb(%rip), %rdx      # 0xcdcb
xorl %r14d, %r14d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x52aa
movq %r14, %rax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq