Created
July 23, 2015 05:56
-
-
Save kolo/88499534f4b461c40ec5 to your computer and use it in GitHub Desktop.
digest implementation for http digest authentication
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"crypto/md5" | |
"fmt" | |
"strings" | |
) | |
type digest struct { | |
username string | |
password string | |
realm string | |
uri string | |
method string | |
nonce string | |
nc int | |
cnonce string | |
qop string | |
opaque string | |
} | |
func (d *digest) ha1() string { | |
s := strings.Join([]string{d.username, d.realm, d.password}, ":") | |
return fmt.Sprintf("%x", md5.Sum([]byte(s))) | |
} | |
func (d *digest) ha2() string { | |
s := strings.Join([]string{d.method, d.uri}, ":") | |
return fmt.Sprintf("%x", md5.Sum([]byte(s))) | |
} | |
func (d *digest) response() string { | |
s := strings.Join([]string{d.ha1(), d.nonce, fmt.Sprintf("%08x", d.nc), d.cnonce, d.qop, d.ha2()}, ":") | |
return fmt.Sprintf("%x", md5.Sum([]byte(s))) | |
} | |
func (d *digest) String() string { | |
params := map[string]string{ | |
"username": fmt.Sprintf("%q", d.username), | |
"realm": fmt.Sprintf("%q", d.realm), | |
"nonce": fmt.Sprintf("%q", d.nonce), | |
"uri": fmt.Sprintf("%q", d.uri), | |
"qop": d.qop, | |
"nc": fmt.Sprintf("%08x", d.nc), | |
"cnonce": fmt.Sprintf("%q", d.cnonce), | |
"response": fmt.Sprintf("%q", d.response()), | |
"opaque": fmt.Sprintf("%q", d.opaque), | |
} | |
values := []string{} | |
for k, v := range params { | |
values = append(values, fmt.Sprintf("%s=%s", k, v)) | |
} | |
return strings.Join(values, ", ") | |
} | |
func (d *digest) Header() string { | |
return fmt.Sprintf("Digest %s", d.String()) | |
} | |
func parseDigest(v string) map[string]string { | |
params := map[string]string{} | |
t := strings.SplitN(v, " ", 2) | |
if len(t) < 2 { | |
return params | |
} | |
for _, p := range strings.Split(t[1], ",") { | |
t := strings.SplitN(p, "=", 2) | |
if len(t) == 2 { | |
params[strings.TrimSpace(t[0])] = strings.Trim(t[1], "\" ") | |
} | |
} | |
return params | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment