code: public static SignedDuoCookie parseSignedDuoCookie(String key, String str)
              throws GuacamoleException {
  
          // Verify format of provided data
          Matcher matcher = SIGNED_COOKIE_FORMAT.matcher(str);
          if (!matcher.matches())
              throw new GuacamoleClientException("Format of signed Duo cookie "
                      + "is invalid.");
  
          // Parse type from prefix
          Type type = Type.fromPrefix(matcher.group(PREFIX_GROUP));
          if (type == null)
              throw new GuacamoleClientException("Invalid Duo cookie prefix.");
  
          // Parse cookie from base64-encoded data
          DuoCookie cookie = DuoCookie.parseDuoCookie(matcher.group(DATA_GROUP));
  
          // Verify signature of cookie
          SignedDuoCookie signedCookie = new SignedDuoCookie(cookie, type, key);
          if (!signedCookie.getSignature().equals(matcher.group(SIGNATURE_GROUP)))
              throw new GuacamoleClientException("Duo cookie has incorrect signature.");
  
          // Cookie has valid signature and has parsed successfully
          return signedCookie;
  
      }
docs: Parses a signed Duo cookie string, such as that produced by the
  toString() function or received from the Duo service, producing a new
  SignedDuoCookie object containing the associated cookie data and
  signature. If the given string is not a valid Duo cookie, or if the
  signature is incorrect, an exception is thrown. Note that the cookie may
  be expired, and must be checked for expiration prior to actual use.
  
  @param key
  The key that was used to sign the Duo cookie.
  
  @param str
  The Duo cookie string to parse.
  
  @return
  A new SignedDuoCookie object containing the same data and signature
  as the given Duo cookie string.
  
  @throws GuacamoleException
  If the given string is not a valid Duo cookie string, or if the
  signature of the cookie is invalid.